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)
您可以使用wait命令:
(echo starting & sleep 10 & wait) && echo done
Run Code Online (Sandbox Code Playgroud)
您可以看到“开始”行立即发生,“完成”行等待 10 秒。