问题
I have a python script that takes several hours to complete. I usually run it as:
python myscript.py arg1 arg2 ... argN 2> log.err > log.out &
I'd like to have a shell script that runs several time the same python script (with different parameters). This script has to start the second python script ONLY when the first one has terminated and so on. I think I should use PID of the processes and iteratively check using sleep within some while loops. Any suggestions? The scripts are executed in a remote machine so I have to put them in background in order the guarantee they keep executing even when I log out.
回答1:
Instead of backgrounding each invocation of python, use a script which runs all the jobs one by one and background the script. For example:
#!/bin/sh
python myscript.py arg1 arg2 ... argN 2> log.err > log.out
python myscript.py different_args
# etc.
Make the script executable (chmod +x script.sh
) and run it from the shell like ./script.sh &
Perhaps you should take a look at a tool like screen
, which will keep your jobs running after you log off. If you do screen ./script.sh
, then detach (ctrl-a-d
) and log off, your script will continue to run. Then you can log back in later and reattach with screen -r
.
回答2:
Make a bash script?
python first.py
python second.py
回答3:
If you want one script to run directly after the other, simply drop the trailing &
. The ampersand tells bash to run the process in the background, which allows you to run multiple processes in parallel (some in the background, and some in the foreground). If you want to run them sequentially, you should run them each in the foreground, like so:
python myscript.py argX1 argX2 ... argXN 2> logX.err > logX.out
python myscript.py argY1 argY2 ... argYN 2> logY.err > logY.out
This will run the script with the argx arguments, then, after that finishes, run the same script again with the argY arguments.
If you want the next execution to run only if the first run is successful, you can use the double ampersand (&&
) like so (note that the trailing backslash (\
) escapes the newline, so the entire thing is actually a single command):
python myscript.py argx1 argx2 ... argN 2> logx.err > logx.out && \
python myscript.py argy1 argy2 ... argN 2> logy.err > logy.out
You can chain more than two commands with double ampersands, but for longer scripts, you should consider using set -e
at the beginning, which will cause bash to stop executing the script after the first error (see http://www.davidpashley.com/articles/writing-robust-shell-scripts/#id2382181)
回答4:
For example, you can use cycle (make a script runner.sh
with the next content:
n=0
while read -r line
do
let n++
echo python myscript.py $line #>log.$n.log 2>log.$n.err
done <<ARGS
a1 a2 a3 a4
b1 b2
c1 c2 c3 c4
ARGS
this will dry run
your python script with args
a1 a2 a3 a4
b1 b2
c1 c2 c3 c4
sequentially, e.g. when the previous ends.
If you satisfied, remove the echo
and the #
from the line
echo python myscript.py $line #>log.$n.log 2>log.$n.err
The log files will be numbered in sequence... 1..n
.
Why do you want run the python
script in the background? You always can send to background the above script and the whole sequence will be done in the bg
.
If you need run it after the logout, use the above runner.sh
as
chmod 755 runner.sh
nohup runner.sh
logout
or much better use the screen
utility, and you can logout and login from another place and re-attach the session and so on... read man screen
.
来源:https://stackoverflow.com/questions/25107089/run-python-script-after-another-is-terminated