如何正确轮询后台脚本是否存在

如何正确轮询后台脚本是否存在

我对以下类型的脚本有问题:

  #!/bin/sh

  long_running_script.sh &  

  while [ `pidof long_running_script.sh` ]
  do
    echo "."
    sleep 1
  done

该脚本将在后台启动一个新脚本,并且它应该打印点,直到后台脚本退出。当CPU负载不高时它可以工作。

但是,当 CPU 负载较高时,它将不起作用:long_running_script.sh 将启动,但“父”脚本将在 long_running_script.sh 退出之前从 while 循环退出。

似乎是pidof在 long_running_script.sh 真正启动(执行)之前执行的。

解决这个问题的最佳方法是什么?

while 语句之前睡眠 1 秒没有帮助。所以我不想使用任何魔法延迟,因为它可能不可靠。

答案1

pidof不会找到脚本,因为它只查看进程名称的第一部分 ( argv[0])。

你可以使用pidof -m,但这会发现任何 long_running_script.sh,不仅仅是由该脚本启动的。

更好的方法是使用$!变量,它保存最近后台作业的 PID。

#!/bin/bash

long_running_script.sh &  
pid=$!

while ps -p $pid >/dev/null
do
    echo "."
    sleep 1
done

答案2

如果您不希望阻塞,wait我会使用 bash 的内置作业控制功能来解决这个问题。对于只有一个分叉和执行的进程来说,这非常简单,我的方法如下所示

#!/bin/sh

sleep 1 &

while jobs | grep -q "Running" ; do
    echo -n "."     # no trailing newline
    sleep 0.1
done

echo 

答案3

使用wait

#!/bin/sh
  long_running_script.sh &  
  wait
  echo "done"

更多细节

相关内容