当前位置:  开发笔记 > 编程语言 > 正文

如何从bash脚本并行运行多个程序?

如何解决《如何从bash脚本并行运行多个程序?》经验,为你挑选了11个好方法。

我正在尝试编写一个同时运行许多程序的.sh文件

我试过这个

prog1 
prog2

但是运行prog1然后等到prog1结束然后开始prog2 ...

那我怎么能并行运行呢?



1> Ory Band..:

怎么样:

prog1 & prog2 && fg

这将:

    开始prog1.

    将其发送到后台,但继续打印输出.

    启动prog2,并将其保持在前台,以便您可以将其关闭ctrl-c.

    当你关闭prog2,你会回到prog1前景,所以你也可以关闭它ctrl-c.


试过这个,它对我没有预期的效果.然而,稍作改动:`prog1&prog2; fg`这是为了同时运行多个ssh隧道.希望这有助于某人.
@ jnadro52一次终止两个进程的方法是`prog1&prog2 && kill $!`.
当`prog2`终止时,是否有一种简单的方法来终止`prog1`?想想`node srv.js&cucumberjs`
非常好,正是我想要的!
在SSH'ed shell上如果你执行这样的命令,杀死prog1将是棘手的.Ctrl-c对我不起作用.甚至杀死整个终端也让prog1继续运行.
@ jnadro52你的解决方案的效果是,如果`prog2`无法立即运行,你将回到前台有'prog1`.如果这是可取的,那就没关系.

2> psmears..:
prog1 &
prog2 &


别忘了'等等'!是的,在bash中,您可以等待脚本的子进程.
另一种选择是使用`nohup`来防止程序在shell挂起时被杀死.

3> Ole Tange..:

使用GNU Parallel http://www.gnu.org/software/parallel/,它很简单:

(echo prog1; echo prog2) | parallel

或者如果您愿意:

parallel ::: prog1 prog2

学到更多:

观看介绍视频以获得快速介绍:https: //www.youtube.com/playlist?list = PL284C9FF2488BC6D1

阅读教程(man parallel_tutorial).你的命令行会爱你.


值得注意的是,有不同版本的`parallel`具有不同的语法.例如,在Debian衍生物上,`moreutils`包中包含一个名为`parallel`的不同命令,它的行为完全不同.
是'并行'比使用`&`更好?
@OptimusPrime这真的取决于.GNU Parallel引入了一些开销,但作为回报,您可以更好地控制正在运行的作业和输出.如果两个作业同时打印,GNU Parallel将确保输出不混合.

4> trusktr..:

你可以使用wait:

some_command &
P1=$!
other_command &
P2=$!
wait $P1 $P2

它将后台程序PID分配给变量($!是最后一个启动的进程'PID),然后wait命令等待它们.这很好,因为如果你杀死脚本,它也会杀死进程!


[根据我的经验](https://i.imgur.com/BpPhYaP.png),查杀等待也不会杀死其他进程.

5> Quinn Comend..:

如果你想能够轻松地运行并杀死多个进程ctrl-c,这是我最喜欢的方法:在(…)子shell中生成多个后台进程,并SIGINT执行trap kill 0,这将杀死子shell组中生成的所有内容:

(trap 'kill 0' SIGINT; prog1 & prog2 & prog3)

你可以有复杂的流程执行结构,一切都将关闭单ctrl-c(只需确保最后的过程是在前台运行,即没有一个包括&prog1.3):

(trap 'kill 0' SIGINT; prog1.1 && prog1.2 & (prog2.1 | prog2.2 || prog2.3) & prog1.3)



6> fermin..:
#!/bin/bash
prog1 & 2> .errorprog1.log; prog2 & 2> .errorprog2.log

将错误重定向到单独的日志.


您必须在重定向后放入&符号并省略分号(&符号也将执行命令分隔符的功能):`prog1 2> .errorprog1.log&prog2 2> .errorprog2.log&`
它不起作用 - 错误不会重定向到文件.试试:`ls notthere1&2> .errorprog1.log; ls notthere2&2> .errorprog2.log`.错误转到控制台,两个错误文件都是空的.正如@Dennis Williamson所说,`&`是一个分隔符,就像```,所以(a)它需要在命令的最后(在任何重定向之后),以及(b)你不需要`; `at all :-)

7> 3h4x..:

有一个非常有用的程序叫nohup.

     nohup - run a command immune to hangups, with output to a non-tty


`nohup`本身不会在后台运行任何东西,并且使用`nohup`不是在后台运行任务的必要条件或先决条件.它们通常在一起使用,但因此,这并不能回答这个问题.

8> mklement0..:

xargs -P 允许您并行运行命令。

尽管这-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所有命令完成之前,命令本身不会返回,但是您可以在后台执行该操作&,方法是使用控制操作符终止该命令,然后使用wait内置函数等待整个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要求指定命令的计数并行运行明确,而GNU xargs允许你指定-P 0要尽可能多的运行尽可能平行。

并行运行的进程的输出在生成时会到达,因此将无法预料地交错

parallel如Ole的回答中所述(大多数平台都不标准),GNU可以方便地在每个进程的基础上对输出进行序列化(分组),并提供更多高级功能。



9> ljt..:

你可以尝试ppss.ppss相当强大 - 你甚至可以创建一个迷你集群.如果你有一批令人尴尬的并行处理,xargs -P也很有用.



10> Joaopcribeir..:

我最近有类似的情况,我需要同时运行多个程序,将它们的输出重定向到分离的日志文件并等待它们完成,我最终得到类似的东西:

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



11> arnaldocan..:

这是我使用的函数,以便并行运行max n进程(在示例中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设置为内核数,则此函数将尝试避免空闲内核.

推荐阅读
周扒pi
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有