如何等待第一个命令完成?

Pra*_*kar 19 linux bash

我正在用bash编写一个脚本,它在内部调用两个bash脚本.第一个脚本包括在后台运行的不同测试和第二个脚本打印第一个脚本的结果.

当我一个接一个地运行这两个脚本时,有时,第二个脚本会在第一个脚本结束之前执行,这会打印出错误的结果.

我正在使用source命令运行这两个脚本.有更好的建议吗?

source ../../st_new.sh -basedir $STRESS_PATH -instances $INSTANCES 
source ../../results.sh
Run Code Online (Sandbox Code Playgroud)

Aar*_*lla 28

Shell脚本,无论它们如何执行,都会在另一个之后执行一个命令.所以你的代码将results.sh在最后一个命令st_new.sh完成后执行.

现在有一个特殊的命令搞砸了这个: &

cmd &
Run Code Online (Sandbox Code Playgroud)

表示:"启动一个新的后台进程并cmd在其中执行.启动后台进程后,立即继续执行脚本中的下一个命令."

这意味着&不等待cmd它的工作.我的猜测是st_new.sh包含这样一个命令.如果是这种情况,那么您需要修改脚本:

cmd &
BACK_PID=$!
Run Code Online (Sandbox Code Playgroud)

这会将新后台进程的进程ID(PID)放入变量中BACK_PID.然后,您可以等待它结束:

while kill -0 $BACK_PID ; do
    echo "Process is still active..."
    sleep 1
    # You can add a timeout here if you want
done
Run Code Online (Sandbox Code Playgroud)

或者,如果您不想要任何特殊处理/输出

wait $BACK_PID
Run Code Online (Sandbox Code Playgroud)

请注意,某些程序在运行时会自动启动后台进程,即使您省略了&.查看文档,他们通常可以选择将PID写入文件,或者可以使用选项在前台运行它们,然后使用shell &命令来获取PID.

  • @walknotes:你可以,但最终有人会插入一个无辜的 `echo "Waiting for PID $!"`,之后 `$!` 将是 echo 的 PID ...或者不是,当 `echo` 是 shell 内置时。这可能意味着脚本在不同的 shell 上表现不同。经验法则:如果您需要自动变量,请复制一份。 (3认同)

Wal*_*r A 5

确保 st_new.sh 最后做了一些你能识别的事情(比如 touch /tmp/st_new.tmp 当你首先删除文件并总是启动 st_new.sh 的一个实例时)。
然后进行轮询循环。首先睡眠您认为应该等待的正常时间,并在每个循环中等待很短的时间。这将导致类似

max_retry=20
retry=0
sleep 10 # Minimum time for st_new.sh to finish
while [ ${retry} -lt ${max_retry} ]; do
   if [ -f /tmp/st_new.tmp ]; then
      break # call results.sh outside loop
   else
      (( retry = retry + 1 ))
      sleep 1
   fi
done
if [ -f /tmp/st_new.tmp ]; then
   source ../../results.sh 
   rm -f /tmp/st_new.tmp
else
   echo Something wrong with st_new.sh
fi
Run Code Online (Sandbox Code Playgroud)