如何等待在另一个 shell 中启动的程序

hil*_*red 22 process shell-script

我有一个程序可以完成大量工作(大约需要 4-5 个小时),当它使用的所有数据都可用时,它会由 cron 启动。有时,当我等待它完成时,我希望能够在它完成时启动另一个(交互式)程序。等待电话看起来很有希望,但只会等待孩子。

Emm*_*uel 15

我绝对更喜欢EDIT #3解决方案(见下文)。

如果它不在同一个 shell 中,请使用while循环,条件为ps -p返回 true。把睡眠中循环,以减少处理器的使用。

while ps -p <pid> >/dev/null 2>&1
do
   sleep 10
done 
Run Code Online (Sandbox Code Playgroud)

或者如果您的 UNIX 支持 /proc(例如 HP-UX 仍然不支持)。

while [[ -d /proc/<pid> ]]
do 
    sleep 10
done
Run Code Online (Sandbox Code Playgroud)

如果你想要超时

timeout=6  # timeout after 1mn  
while ((timeout > 0)) && ps -p <pid> >/dev/null 2>&1
do
   sleep 10
   ((timeout -= 1))
done 
Run Code Online (Sandbox Code Playgroud)

编辑#1

还有另一种方法:不要使用cron。使用批处理命令堆叠您的作业。

例如,您可以每天堆叠所有工作。可以调整批处理以允许一些并行性,因此阻塞的作业不会停止所有堆栈(这取决于操作系统)。

编辑#2

在您的主目录中创建一个 fifo:

$ mkfifo ~/tata
Run Code Online (Sandbox Code Playgroud)

在你的工作结束时:

echo "it's done" > ~/tata
Run Code Online (Sandbox Code Playgroud)

在另一份工作(正在等待的人)开始时:

cat ~/tata 
Run Code Online (Sandbox Code Playgroud)

它不是轮询它是旧的好阻塞 IO。

编辑 #3

使用信号:

在脚本开始时谁正在等待:

echo $$ >>~/WeAreStopped
kill -STOP $$
Run Code Online (Sandbox Code Playgroud)

在你的长期工作结束时:

if [[ -f ~/WeAreStopped ]] ; then
    xargs kill -CONT < ~/WeAreStopped
    rm ~/WeAreStopped
fi
Run Code Online (Sandbox Code Playgroud)


rus*_*ush 5

您可以修改您的 cron 作业以使用一些标志。

代替

2  2 * * *           /path/my_binary
Run Code Online (Sandbox Code Playgroud)

您可以使用

2  2 * * *           touch /tmp/i_m_running; /path/my_binary; rm /tmp/i_m_running
Run Code Online (Sandbox Code Playgroud)

只需在脚本中甚至手动监控此文件。如果它存在,那么你的程序正在运行;否则随意做任何你想做的事。

脚本示例:

while [[ -f /tmp/i_m_running ]] ; do
   sleep 10 ;
done
launch_whatever_you_want
Run Code Online (Sandbox Code Playgroud)

如果您不喜欢使用sleep,您可以修改脚本并每 X 分钟通过 cron 运行一次。

在这种情况下,脚本示例将是:

[[ -f /tmp/i_m_running ]] && { echo "Too early" ; exit ; }
launch_whatever_you_want
Run Code Online (Sandbox Code Playgroud)

这种方式更容易一些,因为您不必找到您的 cron 进程的 PID。