And*_*rew 22 bash shell-script background-process parallelism
假设我有三个(或更多)的bash脚本:script1.sh
,script2.sh
,和script3.sh
。我想调用所有这三个脚本并并行运行它们。一种方法是执行以下命令:
nohup bash script1.sh &
nohup bash script2.sh &
nohup bash script3.sh &
Run Code Online (Sandbox Code Playgroud)
(通常,脚本可能需要几个小时或几天才能完成,所以我想使用nohup
它们以便即使我的控制台关闭它们也能继续运行。)
但是,有没有办法通过一次调用并行执行这三个命令?
我在想像
nohup bash script{1..3}.sh &
Run Code Online (Sandbox Code Playgroud)
但这似乎是按顺序执行script1.sh
,script2.sh
而script3.sh
不是并行执行。
Hau*_*ing 17
for((i=1;i<100;i++)); do nohup bash script${i}.sh & done
Run Code Online (Sandbox Code Playgroud)
Kan*_*han 16
更好的方法是使用GNU Parallel。GNU 并行很简单,有了它,我们可以控制并行运行的作业数量,并对作业进行更多控制。
在下面的命令中,script{1..3}.sh
被扩展并作为参数bash
并行发送。这里-j0
表示应该运行尽可能多的作业。默认情况下,parallel
为一个 CPU 内核运行一项作业。
$ parallel -j0 bash :::: <(ls script{1..3}.sh)
Run Code Online (Sandbox Code Playgroud)
你也可以尝试使用
$ parallel -j0 bash ::: script{1..3}.sh
Run Code Online (Sandbox Code Playgroud)
在执行第二种方法时,如果您收到任何错误消息,则意味着该--tollef
选项已设置/etc/parallel/config
并且需要删除,并且一切都会正常进行。
您可以在此处阅读GNU Parallels
手册页以获得更丰富的选项。
如果您从远程机器运行作业,请更好地使用,screen
以免会话因网络问题而关闭。nohup
不是必需的,因为最新版本的 bash 随附了huponexit
as off
,这将阻止父 shellHUP
在退出时向其子shell 发送信号。如果它没有取消设置,请使用
$ shopt -u huponexit
Run Code Online (Sandbox Code Playgroud)
我们还可以使用xargs
并行运行多个脚本。
$ ls script{1..5}.sh|xargs -n 1 -P 0 bash
Run Code Online (Sandbox Code Playgroud)
这里每个脚本都作为参数分别传递给 bash。-P 0
表示并行进程的数量可以尽可能多。使用 bash default 也更安全job control feature
(&)
。
单个线的解决方案:
$ nohup bash script1.sh & nohup bash script2.sh & nohup bash script3.sh &
Run Code Online (Sandbox Code Playgroud)
不那么滑稽,只需使用包装脚本:
$ cat script.sh
#!/usr/bin/env bash
script1.sh &
script2.sh &
script3.sh &
$ nohup script.sh &
Run Code Online (Sandbox Code Playgroud)
或者循环它们:
for script in dir/*.sh
do
nohup bash "$script" &
done
Run Code Online (Sandbox Code Playgroud)