8

I have been working on a script mixture of bash and python script. The bash script can receive unknown count input arguments. For example :

tinify.sh  test1.jpg test2.jpg test3.jpg .....

After the bash receives all, it pass these arguments to tinify.py. Now I have come out two ways to do that.

  • Loop in bash and call python tinify.py testx.jpg

    In another word, python tinify test1.jpg then python tinify test2.jpg, finaly python tinify test3.jpg

  • Pass all arguments to tinify.py then loop in python

But there is a problem, I want to filter same parameter for example if user input tinify.sh test1.jpg test1.jpg test1.jpg , I only want tinify.sh test1.jpg.So I think it's easier to do in second way because python may be convenient.

How can I do to pass all arguments to python script? Thanks in advance!

CoXier
  • 2,523
  • 8
  • 33
  • 60

4 Answers4

8

In addition to Chepner's answer above:

#!/bin/bash
tinify.py "$@"

within python script, tinify.py:

from sys import argv
inputArgs = sys.argv[1:]
def remove_duplicates(l):
    return list(set(l))
arguments=remove_duplicates(inputArgs)

The list arguments will contain the arguments passed to python script (duplicated removed as set can't contain duplicated values in python).

Ardit
  • 1,522
  • 17
  • 23
5

You use $@ in tinify.sh

#!/bin/bash
tinify.py "$@"

It will be far easier to eliminate duplicates inside the Python script that to filter them out from the shell. (Of course, this raises the question whether you need a shell script at all.)

chepner
  • 497,756
  • 71
  • 530
  • 681
  • I agree that elimination of duplicates are way better accomplished in Python. I agree that the use of the bash script here is really superficial. However, this is already pointed out in previous comments. The OP asks how to filter the arguments in bash. Not in Python. – Wololo Sep 22 '17 at 13:29
  • I think sometimes it's more convenient to use `./tinify.sh test1.jpg test2.jpg` than `python tinify.py test1.jpg test2.jpg` although they both works well for me. Is there any other convenient way to invoke them ? – CoXier Sep 22 '17 at 13:30
  • If you add `#!/usr/bin/python` (or whatever is appropriate) to the Python script and make it executable, you can simply run `./tinify.py test1.jpg test2.jpg`. – chepner Sep 22 '17 at 13:57
1

A python program can accept any number of command line arguments, using sys.argv — just remember that sys.argv[0] is the name of the script and actual arguments are contained in sys.argv[1:]

$ cat test_args.py
from sys import argv

prog_name = argv[0]
print('Program name:', prog_name)

for arg in argv[1:]:
    print(arg)
$ python test_args.py a b 'c d'
Program name: test_args.py
a
b
c d
$

note that an argument containing spaces must be quoted according to the shell syntax.

gboffi
  • 22,939
  • 8
  • 54
  • 85
  • Do you understand my question ? I do not know how to pass all arguments from bash script to python. – CoXier Sep 22 '17 at 13:04
  • Do you understand my answer? You can write the Python part so that the shell can pass any number of arguments, e.g.: `python tinify.py $@` if you don't want to touch the arguments. – gboffi Sep 22 '17 at 13:35
0

Your file tinify.py should start with the following (if you have two arguments):

import sys

arg1, arg2 = sys.argv[1], sys.argv[2]

sys.argv[0] is the name of the script itself. You can of course loop over sys.argv. Personally, i like to pass all the arguments as json objects, so afterwards I do json.loads()

Coding thermodynamist
  • 1,340
  • 1
  • 10
  • 18
  • So how can I pass to python script ? – CoXier Sep 22 '17 at 12:34
  • 1
    Regarding the problem with unique args ```tinify.sh test1.jpg test1.jpg test1.jpg``` should become ```tinify.sh test1.jpg```, you could use a set. For example ```set([sys.argv[i] for i in range(your_number_of_args)])``` – ConorSheehan1 Sep 22 '17 at 12:35
  • Thanks a lot @con-- – CoXier Sep 22 '17 at 12:36
  • 2
    No problem. You pass the args to the python script the same way as the bash script. If you call ```tinify.py test1.jpg``` sys.argv[1] will be "test1.jpg". If you want a variable number of args you can count the args using ```len(sys.argv)``` Within the bash script I think you can pass all args using "$@". Taken from [this](https://stackoverflow.com/questions/3811345/how-to-pass-all-arguments-passed-to-my-bash-script-to-a-function-of-mine) answer – ConorSheehan1 Sep 22 '17 at 12:39