emr*_*rah 11 bash shell-script
我有两个使用 GPU 和训练 ML 模型的脚本。我想在睡觉前启动它们,这样它们就可以在晚上工作,我希望在早上看到一些结果。
但是由于 GPU 内存有限,我想串行而不是并行运行它们。
我可以做到python train_v1.py && python train_v2.py
;但假设我开始训练train_v1
. 同时,由于训练时间较长,我开始并完成了第二个脚本的实现train_v2.py
,我想在python train_v1.py
完成时自动运行它。
我怎样才能做到这一点?谢谢你。
JoL*_*JoL 29
这是一种方法,它不涉及循环和检查另一个进程是否还活着,或者train_v1.py
以与您通常所做的不同的方式调用:
$ python train_v1.py
^Z
[1]+ Stopped python train_v1.py
$ % && python train_v2.py
Run Code Online (Sandbox Code Playgroud)
该^Z
是我按下Ctrl+ Z,而正在运行的进程睡眠train_v1.py
通过发送一个SIGTSTP
信号。然后,我告诉 shell 用 唤醒它%
,使用它作为我可以&& python train_v2.py
在最后添加的命令。这使得它的行为就像你python train_v1.py && python train_v2.py
从一开始就做的一样。
取而代之的是%
,您还可以使用fg
. 这是同一件事。如果您想了解有关 shell 的这些类型功能的更多信息,可以在bash 联机帮助页的“作业控制”部分中阅读有关它们的信息。
正如 jamesdlin 在评论中指出的那样,如果您尝试train_v3.py
在 v2 启动之前继续添加模式,您会发现您不能:
$ % && python train_v2.py
^Z
[1]+ Stopped python train_v1.py
Run Code Online (Sandbox Code Playgroud)
只会train_v1.py
因为train_v2.py
尚未开始而停止,并且您无法停止/暂停/睡眠甚至尚未开始的东西。
$ % && python train_v3.py
Run Code Online (Sandbox Code Playgroud)
将导致相同
python train_v1.py && python train_v3.py
Run Code Online (Sandbox Code Playgroud)
因为%
对应于最后一个挂起的进程。与其尝试这样添加v3
,不如使用历史记录:
$ !! && python train_v3.py
% && python train_v2.py && python train_v3.py
Run Code Online (Sandbox Code Playgroud)
可以像上面那样进行历史扩展,或者使用键绑定(如 up)调用最后一个命令并将 v3 添加到最后。
$ % && python train_v2.py && python train_v3.py
Run Code Online (Sandbox Code Playgroud)
这是可以重复的东西,以向管道添加更多内容。
$ !! && python train_v3.py
% && python train_v2.py && python train_v3.py
^Z
[1]+ Stopped python train_v1.py
$ !! && python train_v4.py
% && python train_v2.py && python train_v3.py && python train_v4.py
Run Code Online (Sandbox Code Playgroud)
Kus*_*nda 11
如果您已经开始python train_v1.py
,您可能会使用pgrep
轮询该进程直到它消失,然后运行您的第二个 Python 脚本:
while pgrep -u "$USER" -fx 'python train_v1.py' >/dev/null
do
# sleep for a minute
sleep 60
done
python train_v2.py
Run Code Online (Sandbox Code Playgroud)
通过使用-f
and-x
匹配用于启动第一个 Python 脚本的确切命令行。在某些系统上,pgrep
实现一个-q
选项,使其安静(就像grep -q
),这意味着/dev/null
不需要重定向到。
该-u
选项将匹配限制为您正在运行的命令(而不是同一系统上的朋友或其他人)。
如果你还没有开始第一个脚本:
正如评论中提到的,您可以在第一个脚本之后直接启动第二个脚本。第二个脚本不存在或尚未准备好运行的事实并不重要(只要它准备好在第一个脚本完成时运行):
python train_v1.py; python train_v2.py
Run Code Online (Sandbox Code Playgroud)
无论第一个脚本的退出状态如何,这样做都会启动第二个脚本。使用&&
而不是;
,正如您在问题中所示,也可以工作,但需要第一个脚本成功完成才能启动第二个脚本。
您可以启动第一个脚本
python train_v1.py; touch finished
Run Code Online (Sandbox Code Playgroud)
然后简单地创建一个循环,定期检查是否finished
存在:
while [ ! -f finished ] ; do
sleep 5
done
python train_v2.py
rm finished
Run Code Online (Sandbox Code Playgroud)