【问题标题】:How to be notified when a script's background job completes?如何在脚本的后台作业完成时收到通知?
【发布时间】:2010-05-08 20:06:34
【问题描述】:

我的问题与one 非常相似,只是我的后台进程是从脚本启动的。我可能做错了什么,但是当我尝试这个简单的例子时:

#!/bin/bash
set -mb  # enable job control and notification
sleep 5  &

当睡眠后台命令完成时,我从未收到通知。但是,如果我直接在终端中执行相同的操作,

$ set -mb  
$ sleep 5  &
$
[1]+  Done                    sleep 5

我看到了我期望的输出。

我在 cygwin 上使用 bash。我猜这可能与输出指向的位置有关,但是尝试了各种输出重定向,我没有更接近。

编辑:所以我有更多关于原因的信息(感谢 jkramer),但仍在寻找方法。如何获得从脚本启动的后台进程已终止的“推送”通知?将 PID 保存到文件并轮询不是我想要的。

【问题讨论】:

    标签: bash scripting background jobs notify


    【解决方案1】:

    如果你将它作为源文件运行。然后它可以通知。例如

    cat foo.sh
    
    #!/bin/bash
    set -mb  # enable job control and notification
    sleep 5  &
    
    . foo.sh
    [1]+  Done                    sleep 5
    

    【讨论】:

    • 这套 -b 是我一直在寻找的神奇选项。来自 tcsh,我期待“设置通知”能够工作......
    【解决方案2】:

    shell 的作业控制只影响终端控制的进程,即直接从 shell 启动的任务。

    当父进程(您的脚本)死亡时,init 进程会自动成为子进程(您的 sleep 命令)的父进程,从而有效地终止所有输出。试试这个例子:

    [jkramer/sgi5k:~]# cat foo.sh
    #!/bin/bash
    
    sleep 20 &
    echo $!
    [jkramer/sgi5k:~]# bash foo.sh 
    19638
    [jkramer/sgi5k:~]# ps -ef | grep 19638
    jkramer  19638     1  0 23:08 pts/3    00:00:00 sleep 20
    jkramer  19643 19500  0 23:08 pts/3    00:00:00 grep 19638
    

    可以看到,脚本终止后sleep的父进程为1,即init进程。如果您需要收到有关您的子进程终止的通知,您可以保存 $!变量(最后创建的进程的PID)在文件或某处,并使用“wait”命令等待其终止。

    【讨论】:

    • 谢谢,jkramer - 非常有用。所以我需要做一些不同的事情,但是使用等待命令否定了将子进程发送到后台的点。我想调用脚本(可以选择后台子进程),然后继续使用同一个终端。如果它正在等待,那么终端将不可用,对吗?因此,如果我保存 PID 以供以后参考,我仍然需要定期轮询以查看它是否已完成,而我希望将通知推送给我。
    猜你喜欢
    • 1970-01-01
    • 2018-12-07
    • 2010-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-25
    相关资源
    最近更新 更多