Shell脚本等待后台命令


12

我正在编写脚本,但是我需要一些我找不到解决方法...

我需要在后台“ command1&”中创建命令,然后在脚本中的某个地方等待命令完成之前再执行command2。基本上,我需要这样:

注意:每个命令都在特定目录中运行!在while循环结束时,我的command1创建了4个目录,其中每个目录都运行特定的进程,因此正在运行的进程总数为4

a=1

while [$a -lt 4 ]

     . command1
   #Generates 1 Process  

     a= `export $a +1`
done

   #Wait until the 4 process end and then run the command2 

    . command2

我已经看到了有关wait带有pid进程号的命令的一些信息,但这也没有用。


你控制command1吗?您是否可以对其进行修改,使其返回4个进程的PID?
terdon

是! 我已经知道了:)
澳门Joao 2014年

我已经相应更新了我的答案。告诉我它是否符合您的期望。
Laurent C.

这个Q与此有关:unix.stackexchange.com/questions/100801/…。唯一的区别是您需要从后台进程获取PID。您可以使用$!变量来获取此变量,并将其传递给wait命令,如我在此处所示。$!包含最后一个后台PID,同时$$包含最后一个进程运行的PID。
slm

3
好的,现在您的脚本根本没有意义。到处都有语法错误和奇怪之处。您能告诉我们实际的脚本吗?为什么要采购命令?为什么不执行它们呢?
terdon

Answers:


22

您可以使用命令wait PID来等待进程结束。

您还可以使用以下命令检索最后一条命令的PID $!

在您的情况下,类似这样的方法将起作用:

command1 & #run command1 in background
PID=$! #catch the last PID, here from command1
command2 #run command2 while command1 is running in background
wait $PID #wait for command1, in background, to end
command3 #execute once command1 ended

编辑后,由于您具有多个PID并且知道它们,因此可以执行以下操作:

command1 & #run command1 in background
PID1=xxxxx
PID2=yyyyy
PID3=xxyyy
PID4=yyxxx
command2 #run command2 while command1 is running in background
wait $PID1 $PID2 $PID3 $PID4 #wait for the four processes of command1, in background, to end
command3 #execute once command1 ended

编辑之后,如果您知道创建的PID(xxxxx,yyyyy,xxyyy,yyxxx),则还可以使用wait和等待的PID列表(请参见man)。如果您不认识它们,也许可以将它们收集到command1中(command1是什么?您自己的脚本吗?)
Laurent C.

最好是确保首先将它们正确分组。请参阅我的答案以了解如何完成此操作。
mikeserv

4

最干净的方法是comamnd1返回已启动进程的PID,wait并按@LaurentC的答案建议在每个进程上使用它们。

另一种方法是这样的:

## Create a log file
logfile=$(mktemp)

## Run your command and have it print into the log file
## when it's finsihed.
command1 && echo 1 > $logfile &

## Wait for it. The [ ! -s $logfile ] is true while the file is 
## empty. The -s means "check that the file is NOT empty" so ! -s
## means the opposite, check that the file IS empty. So, since
## the command above will print into the file as soon as it's finished
## this loop will run as long as  the previous command si runnning.
while [ ! -s $logfile ]; do sleep 1; done

## continue
command2

抱歉,仍然无法正常工作。.我将再次改善我的问题!
澳门Joao 2014年

0

如果使用以下方法,则while循环后可能不需要特殊的“等待所有进程”。循环将等待电流command1完成,然后循环回到顶部。请与任何建议一样小心。请注意,我所做的唯一一件事就是添加& wait $!到您的末尾command1

a=1
while [$a -lt 4 ]
     . command1  & wait $!
   #Generates 1 Process  
     a= `export $a +1`
done
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.