调用多个 bash 脚本并并行运行它们,而不是按顺序运行

And*_*rew 22 bash shell-script background-process parallelism

假设我有三个(或更多)的bash脚本:script1.shscript2.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.shscript2.shscript3.sh不是并行执行。

Hau*_*ing 17

for((i=1;i<100;i++)); do nohup bash script${i}.sh & done
Run Code Online (Sandbox Code Playgroud)

  • 你缺少一个右括号。 (2认同)

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 随附了huponexitas off,这将阻止父 shellHUP在退出时向其子shell 发送信号。如果它没有取消设置,请使用

$ shopt -u huponexit  
Run Code Online (Sandbox Code Playgroud)

  • 不,我并不感到困惑,我要说的是,使用`parallel -j0 bash ::: script{1..3}.sh` 可以更好地解决 OP 的问题 - 这比 `::::` 方法更好因为它避免了进程替换的需要。此外 [解析 ls 输出充满陷阱](http://mywiki.wooledge.org/ParsingLs) (2认同)

Yaa*_*lie 9

我们还可以使用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 (&)


l0b*_*0b0 5

单个线的解决方案:

$ 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)