如何从bash脚本并行运行多个程序?
我正在尝试编写一个同时运行多个程序的.sh文件
我试过这个
prog1 prog2 但是,运行prog1,然后等待prog1结束,然后启动prog2 …
那么我怎样才能平行运行呢?
 prog1 & prog2 & 
怎么样:
 prog1 & prog2 && fg 
这会:
-  开始prog1。
- 发送到后台,但不断打印输出。
-  启动prog2,并保持在前台 ,所以你可以用ctrl-cclosures它。
-  当你closuresprog2,你将返回到prog1的前景 ,所以你也可以用ctrl-c来closures它。
使用GNU并行http://www.gnu.org/software/parallel/就像下面这样简单:;
 (echo prog1; echo prog2) | parallel 
或者如果你喜欢:
 parallel ::: prog1 prog2 
学到更多:
- 观看介绍video快速介绍: https : //www.youtube.com/playlist?list=PL284C9FF2488BC6D1
- 浏览教程(man parallel_tutorial)。 你的命令行会爱你。
 你可以用wait : 
 some_command & P1=$! other_command & P2=$! wait $P1 $P2 
 它将后台程序PID分配给variables( $!是最后启动的进程的PID),然后wait命令等待它们。 这很好,因为如果你杀死脚本,它也会杀死进程! 
 #!/bin/bash prog1 & 2> .errorprog1.log; prog2 & 2> .errorprog2.log 
redirect错误以分隔日志。
有一个非常有用的程序,叫nohup。
  nohup - run a command immune to hangups, with output to a non-tty 
你可以试试ppss 。 ppss是相当强大的 – 你甚至可以创build一个小型集群。 xargs -P也可以是有用的,如果你有一批尴尬的并行处理。
最近我有类似的情况,我需要同时运行多个程序,将他们的输出redirect到分离的日志文件,等待他们完成,我最终得到了类似的东西:
 #!/bin/bash # Add the full path processes to run to the array PROCESSES_TO_RUN=("/home/joao/Code/test/prog_1/prog1" \ "/home/joao/Code/test/prog_2/prog2") # You can keep adding processes to the array... for i in ${PROCESSES_TO_RUN[@]}; do ${i%/*}/./${i##*/} > ${i}.log 2>&1 & # ${i%/*} -> Get folder name until the / # ${i##*/} -> Get the filename after the / done # Wait for the processes to finish wait 
资料来源: http : //joaoperibeiro.com/execute-multiple-programs-and-redirect-their-outputs-linux/
下面是一个函数,我用它来并行执行最大进程(n = 4)。
 max_children=4 function parallel { local time1=$(date +"%H:%M:%S") local time2="" # for the sake of the example, I'm using $2 as a description, you may be interested in other description echo "starting $2 ($time1)..." "$@" && time2=$(date +"%H:%M:%S") && echo "finishing $2 ($time1 -- $time2)..." & local my_pid=$$ local children=$(ps -eo ppid | grep -w $my_pid | wc -w) children=$((children-1)) if [[ $children -ge $max_children ]]; then wait -n fi } parallel sleep 5 parallel sleep 6 parallel sleep 7 parallel sleep 8 parallel sleep 9 wait 
如果max_children设置为核心数量,此function将尝试避免空闲核心。
  xargs -P <n>允许您并行运行<n>命令。 
 虽然-P是非标准选项,但GNU(Linux)和macOS / BSD实现都支持它。 
下面的例子:
- 一次最多并行运行3个命令,
- 只有当以前启动的进程终止时才会启动附加的命令。
 time xargs -P 3 -I {} sh -c 'eval "$1"' - {} <<'EOF' sleep 1; echo 1 sleep 2; echo 2 sleep 3; echo 3 echo 4 EOF 
输出看起来像是:
 1 # output from 1st command 4 # output from *last* command, which started as soon as the count dropped below 3 2 # output from 2nd command 3 # output from 3rd command real 0m3.012s user 0m0.011s sys 0m0.008s 
时间表明这些命令是并行运行的(最后一个命令是在原始3的第一个终止后才启动的,但是执行得非常快)。
 在所有命令完成之前, xargs命令本身不会返回,但是您可以在后台通过使用控制运算符&终止它,然后使用内build等待来等待整个xargs命令完成。 
 { xargs -P 3 -I {} sh -c 'eval "$1"' - {} <<'EOF' sleep 1; echo 1 sleep 2; echo 2 sleep 3; echo 3 echo 4 EOF } & # Script execution continues here while `xargs` is running # in the background. echo "Waiting for commands to finish..." # Wait for `xargs` to finish, via special variable $!, which contains # the PID of the most recently started background process. wait $! 
注意:
- 
BSD / macOS xargs要求你指定显式并行运行的命令的数量,而GNUxargs允许你指定-P 0来并行运行尽可能多的命令。
- 
并行运行进程的输出在生成时就会到达,所以会不可预测地交错 。 -   GNU parallel,正如Ole的回答中所提到的 (对于大多数平台来说并不是标准的),可以方便地按照每个进程序列化 (分组)输出,并提供许多更高级的function。
 
-   GNU