Run bash while loop in Python - python

I am trying to run a bash while loop inside a Python3.6 script. What I have tried so far is:
subprocess.run(args=['while [ <condition> ]; do <command> done;'])
I get the following error:
FileNotFoundError: [Errno 2] No such file or directory
Is there a way to run such a while loop inside Python?

The part that's tripping you up is providing the args as a list. From the documentation:
If the cmd argument to popen2 functions is a string, the command is executed through /bin/sh. If it is a list, the command is directly executed.
This seems to do what you want:
subprocess.run('i=0; while [ $i -lt 3 ]; do i=`expr $i + 1`; echo $i; done', shell=True)
Notice it's specified as a string instead of a list.

Running bash for loop in Python 3.x is very much like running while loop.
#! /bin/bash
for i in */;
do
zip -r "${i%/}.zip" "$i";
done
This will iterate over a path and zip all directories. To run above bash script in Python:
import subprocess
subprocess.run('for i in */; do zip -r "${i%/}.zip" "$i"; done', shell=True)

Related

How can i make python program to get executed in a loop in bash script?

I have a bash script where to execute the python program within a loop as below. I see only once its getting executed with the below script. The echo statement prints all the filenames in the directory within the loop, whereas the pgm1.py executes only once. Kindly advice what i have to do it here to continuously getting executed for all the files with the directory.
Here is the below code.
LOG_DIR="directorypathname"
DT_H=`date '+%Y-%m-%d_%H_%M_%S'`
linkage_path="directoryname"
yourfilenames=`ls $linkage_path`
for eachfile in $yourfilenames
do
python3.5 ${CODE_DIR}/pgm1.py ${linkage_path}/${eachfile} &> ${LOG_DIR}/${DT_H}.log
echo ${linkage_path}/${eachfile}
done
You got the syntax wrong
for eachfile in $yourfilenames ; do
python3.5 ${CODE_DIR}/pgm1.py ${linkage_path}/${eachfile} &>> \
${LOG_DIR}/${DT_H}.log
echo ${linkage_path}/${eachfile}
done
That should do the trick

Execute shell command in Python: 'Bad substitution'

I would like to batch rename files in several directories
Executing for file in *.jpg; do mv "$file" "${file::19}.jpg";done does it in one directory.
Now I'd like to loop over several like this.
import os
folder = ['/dir_1','/dir_2']
for dir_ in folder:
print(dir_)
os.chdir(dir_)
os.system('for file in *.jpg; do mv "$file" "${file::19}.jpg";done')
However, I get the error sh: 1: Bad substitution
Could someone show me how to do this?
This parameter expansion is called Substring Expansion and is Bash
extension. It works when you're typing it in command line because you
use Bash as your interactive shell but might not work when you use
os.system because it uses /bin/sh which might not be Bash but some
smaller POSIX-compliant shell such as dash. You have to use awk
to do what you want as described
here
like that:
os.system('for file in *.jpg; do mv "$file" "$(echo $file | awk \'{ string=substr($0, 0, 19); print string; }\')".jpg; done')

python, read the filename from directory , use the string in bash script

I am writing a bash script (e.g. program.sh) where I am calling a python code in which a list of files are read from a directory.
the python script (read_files.py) is as following:
import os
def files(path):
for filename in os.listdir('/home/testfiles'):
if os.path.isfile(os.path.join('/home/testfiles', filename)):
yield filename
for filename in files("."):
print (filename)
Now I want to keep the string filename and use it in the bash script.
e.g.
program.sh:
#!/bin/bash
python read_files.py
$Database_maindir/filename
.
.
.
How could I keep the string filename (the names of files in the directory) and write a loop in order to execute commands in bash script for each filename?
The Python script in the question doesn't do anything that Bash cannot already do all by itself, and simpler and easier. Use simple native Bash instead:
shopt -s nullglob
for path in /home/testfiles/*; do
if [[ -f "$path" ]]; then
filename=$(basename "$path")
echo "do something with $filename"
fi
done
If the Python script does something more than what you wrote in the question,
for example it does some complex computation and spits out filenames,
which would be complicated to do in Bash,
then you do have a legitimate use case to keep it.
In that case, you can iterate over the lines in the output like this:
python read_files.py | while read -r filename; do
echo "do something with $filename"
done
Are you looking for something like this? =
for filename in $(python read_files.py); do
someCommand $filename
done

Call multiple python scripts sequentially from a bash script using arguments

I would like to make a bash script that runs some number of python scripts in a row based on arguments given in the terminal (the order in which they run doesn't matter).
Something like:
kwargs = kwarg1 kwarg2 kwarg3
if kwarg1: python script1.py
if kwarg2: python name2000.py
if kwarg3: python program30.py
But with the option to take in any number of keywords as long as they matched up to a script.
How would this be done?
There's a lot you can do to add to this, but here's the simplest of what you're asking for:
#!/bin/bash
for script in $*; do
python $script.py
done
Put that in a new file, e.g. "run_python.bash", and make it executable (chmod a+w run_python.bash).
Then you run it by: run_python.bash one two three, and it will execute one.py, then two.py, then three.py .
If you want to use the if structure in the for loop (i.e. if your keywords don't match the script name), the simple version starts like this:
#!/bin/bash
for script in $*; do
if [ $script == 'kwarg1' ]; then
python script1.py
fi
if [ $script == 'kwarg2' ]; then
python name2000.py
fi
if [ $script == 'kwarg3' ]; then
python program30.py
fi
done
This will execute whatever you tell it to, based on the order of the keywords you put on the command line.
p.s. This has nothing to do with python. The script works the same, whether you're invoking python, or ls, or anything else that you can run in bash.
you need shell script.
script.sh:
#!/bin/bash
if [ "$1" == "kwarg1" ]
then
python script1.py
elif [ "$1" == "kwarg2" ]
then
python name2000.py
fi
chmod +x script.sh
./script.sh kwarg1

jenkins passing in path to python argument as variable

in jenkins i have :
sh 'ls ${workspace}'
sh 'cd MVD/utils && python compareWhitelist.py ${workspace}/MVDZOS'
I want to pass the complete path into the python script because I am doing
os.walk(sys.argv[1])
in the python script, I am also printing out the sys.argv[1] but it is returning only "/MVDZOS". How can I get the complete path into the script?
Try using the Uppercase in quotes.
Ex:
sh 'ls ${workspace}'
sh "cd MVD/utils && python compareWhitelist.py ${WORKSPACE}/MVDZOS"

Categories

Resources