Home > Software design >  How to break a bash for loop from inside a python script?
How to break a bash for loop from inside a python script?

Time:10-16

I have a for loop that runs a python script iteratively. There is a condition inside the python script that, if met, makes unnecessary to keep running the python script or even the for loop. For example:

#Bash Script
for i in {1..15}; do
    echo "Pre Outside ${i}"
    python minimal_test.py $i
    echo "Post Outside ${i}"
done

#Python script
import sys
import subprocess
k = int(sys.argv[1])
end_bash = False

if k == 7:
    end_bash = True
print("Inside "   str(k))
if end_bash:
    bashCommand = "break"
    process = subprocess.Popen(bashCommand, stdout=subprocess.PIPE)

When the loop i in the bash script == 6 and then 7, the program should print:

PreOutside 6
PreInside 6
PostOutside 6    
Pre Outside 7
Pre Inside 7 #The program must end here

However, I get the following error and the program keeps running

File "/software/software/Python/3.9.5-GCCcore-10.3.0/lib/python3.9/subprocess.py", line 1821, in _execute_child
raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'break'

Is there a way to tell bash to end the for loop from inside the python script?

CodePudding user response:

Make your Python script exit with an error. Then the shell script becomes

for i in {1..15}; do
    python minimal_test.py "$i" || break
done

In so many words, your Python script should sys.exit(1) to signal an error to the shell (or any calling utility really). The precise number is up to you; any non-zero number is a failure code. (The range is 0-255, i.e. an unsigned char.)

Running break in a subprocess makes no sense; you were starting a new Bash instance which is independent from the one which is running the loop, one in which of course break doesn't do anything useful, and in fact is just a syntax error in isolation.

  • Related