Bash,如何让一些后台进程运行但等待其他进程?

Ste*_*son 12 shell shell-script background-process

我有(又)其他wait&&&控制流的问题..

假设我有一个类似这样的脚本,我想同时做尽可能多的工作:

# may take some hours
something InputA > IrrelevantA &
something InputB > IrrelevantB &

# may take an hour
(
   somethingElse InputA > OutputA &
   somethingElse InputB > OutputB &
)&& combine OutputA OutputB > Result

...morestuff
Run Code Online (Sandbox Code Playgroud)

问题 1:在脚本中,是否combine在两个somethingElse进程都something继续的同时等待两个进程完成?

问题 2:如果没有 - 我怀疑它没有 - 我如何combine只等待两个somethingElse进程而something上述进程继续在后台工作?

Gra*_*eme 14

在您的示例中,该combine命令将在子 shell 退出后立即运行(并提供最后一个后台进程没有错误启动)。由于没有wait命令,子shell 将在作业启动后立即退出。

如果您想根据两个或多个同时运行的后台进程的返回值来执行命令,那么除了使用临时文件作为返回值之外,我看不到任何其他方式。这是因为wait只能返回它等待的进程之一的返回值。此外,由于后台进程必须在子外壳中运行才能获得它们的返回值,因此它们不能存储在变量中。你可以这样做:

something InputA >IrrelevantA &
something InputB >IrrelevantB &

tmp1=$(mktemp)
tmp2=$(mktemp)

( somethingElse InputA >OutputA; echo $? >"$tmp1" ) &
proc1=$!

( somethingElse InputB >OutputB; echo $? >"$tmp2" ) &
proc2=$!

wait "$proc1" "$proc2"

read ret1 <"$tmp1"
read ret2 <"$tmp2"
[ "$ret1" = 0 && "ret2" = 0 ] && combine OutputA OutputB >Result

rm "$tmp1" "$tmp2"
Run Code Online (Sandbox Code Playgroud)

如果您真的不关心返回值,则可以正常启动作业并使用wait

something InputA >IrrelevantA &
something InputB >IrrelevantB &

somethingElse InputA >OutputA &
proc1=$!

somethingElse InputB >OutputB &
proc2=$!

wait "$proc1" "$proc2"
combine OutputA OutputB >Result
Run Code Online (Sandbox Code Playgroud)


psu*_*usi 3

您可以使用wait命令:

(echo starting & sleep 10 & wait) && echo done
Run Code Online (Sandbox Code Playgroud)

您可以看到“开始”行立即发生,“完成”行等待 10 秒。