Cron 激活 virtualenv 和 运行 来自 shell 脚本的多个 python 脚本

Cron activate virtualenv and run multiple python scripts from shell script

我需要一个 cron 来 运行 一个 shell 脚本。这个 shell 脚本应该激活 python virtualenv 然后执行 python 脚本。 这是我的 cron:

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 开启严格的错误处理。这会在任何 (non-asynchronous) 命令 returns 一个 non-zero 退出代码时立即退出。其次,我会避免使用 &&,因为严格的错误处理会解决这个问题。第三,我会在最后使用 wait 以确保在所有 sub-scripts 退出之前脚本不会退出。

#!/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