我需要一个cron来运行单个shell脚本。这个shell脚本应该激活python virtualenv,然后执行python脚本。这是我的亲信:
0 0 * * 1 /home/ubuntu/crontab_weekly.sh
这是我的crontab_weekly.sh文件:
cd /home/ubuntu/virtualenvironment/scripts
&& source /home/ubuntu/venv3.8/bin/activate
&& python script1.py
& python script2.py
& python script3.py
& python script4.py
这个想法是进入脚本所在的目录,然后激活venv,然后才开始执行脚本。脚本应以并行方式执行。但在我的情况下,只有script1.py被执行,而以下脚本没有被执行。我的问题在哪里?
请记住,&
意味着异步运行整个上一个命令。这包括&&
之前的任何内容。异步运行的命令在单独的进程中运行。
举一个问题的简化示例,假设我们异步更改目录,运行pwd
,然后再次异步运行pwd
。
#!/bin/sh
cd / &&
pwd
& pwd
在我的电脑上,这个输出:
/home/nick
/
cd /
本应影响两个pwd
调用,但它只影响第一个调用,因为第二个调用在不同的进程中运行。(在这种情况下,他们也打印出了问题,第二个先打印。(
那么,如何以更健壮的方式编写这个脚本呢?
首先,我将使用-e
启用严格的错误处理。只要任何(非异步(命令返回非零退出代码,就会退出。其次,我会避免使用&&
,因为严格的错误处理会处理这个问题。第三,我会在最后使用wait
来确保在所有子脚本退出之前脚本不会退出。
#!/bin/sh
set -e
cd /
pwd &
pwd &
wait
一般的想法是打开严格的错误处理,以同步的方式完成所有设置,然后异步启动四个脚本,等待所有脚本完成。
将此应用于您的程序:
#!/bin/sh
set -e
cd /home/ubuntu/virtualenvironment/scripts
source /home/ubuntu/venv3.8/bin/activate
python script1.py &
python script2.py &
python script3.py &
python script4.py &
wait