简体   繁体   中英

How to pass parameters to a python script that will be run using a bash script?

I have a python script which actually does some test and write the results to a file. This python file must be provided with list of arguments:

myPc@myPc:~/Desktop/tests$ ./testScript.py --final fromTo 201983:310029 -o res.txt

Every time I need new result for different ranges I have to do them manually so I decided to write a bash script as follows:

#!/bin/bash

a=`wc -l < inFile.txt`
declare -a periods
declare -i index=0

echo "Number of Periods is: $a"

while IFS='' read -r line || [[ -n "$line" ]]; do
periods[$index]=$line
((index += 1))
done < "inFile.txt"


for ((i=0;i<1300;i++)); do
f1=${period[$i]}
f2=${period[$i+1]}
python testScript.py "--final fromTo $f1:$f2 -o res$i.txt"
done

#END

The ranges are already in a text file so I am reading them and store them into an array.

I wish to use the bash to re-run every time the python script with different ranges until all ranges are covered and all results for all ranges are wrote in a separate file. But I am facing an issue that the parameters I try to pass to python are not even passed. I don't really understand what is the issue in here.

    "--final fromTo $f1:$f2 -o res$i.txt"

this is the parameter I want to pass and once finished I will pass new params and run it again but it seems it is not even looking at them

The quotes around arguments:

python testScript.py "--final fromTo $f1:$f2 -o res$i.txt"

are causing the complete string to be passed as a single argument with spaces to Python script.

By removing quotes (or at least putting them around words):

python testScript.py --final fromTo "$f1:$f2" -o "res$i.txt"

the sys.argv will be populated correctly, and your argument parser will work (note that argparse uses sys.argv by default).


As a little proof, test.py script:

#!/usr/bin/env python
import sys
print(sys.argv)

Now try:

$ python test.py 1 2 3
['test.py', '1', '2', '3']

$ python test.py "1 2 3"
['test.py', '1 2 3']

Unrelated to this, but for completeness' sake, your bash script can be simplified by using the mapfile built-in (aka readarray , available since bash 4.0):

#!/bin/bash
mapfile -t periods <inFile.txt

cnt="${#periods[@]}"
echo "Number of Periods is: $cnt"

for ((i=0; i<cnt; i++)); do
    python testScript.py --final fromTo "${period[$i]}:${period[$i+1]}" -o "res$i.txt"
done

What you type on the commandline is six strings: "./testScript.py" "--final" "fromTo" "201983:310029" "-o" "res.txt"

$ cat args.py
#!/usr/bin/env python
import sys
print sys.argv
$ ./args.py --final fromTo 201983:310029 -o res.txt
['./args.py', '--final', 'fromTo', '201983:310029', '-o', 'res.txt']

When you put double-quotes around the last four strings, you force your shell to treat them as a single string. Not Python's fault.

./args.py "--final fromTo 201983:310029 -o res.txt"
['./args.py', '--final fromTo 201983:310029 -o res.txt']

Just put the quotes around the items that must be handled as single strings:

$ f1=201983; f2=310029; i=1
$ ./args.py --final fromTo "$f1:$f2" -o "res$i.txt"
['./args.py', '--final', 'fromTo', '201983:310029', '-o', 'res1.txt']

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM