根据pid $$监听进程的退出


16

说我手里有个小屁孩, mypid=$$

我可以使用某些bash / system命令来侦听具有给定pid的该进程的退出吗?

如果不存在使用mypid的进程,我猜该命令应该只是失败。


我不使用C#,但是显然必须有一种方法:msdn.microsoft.com/en-us/library/fb4aw7b8(v=vs.110).aspx
Alexander Mills,

在Unix中,通常会等待在shell或C库函数中使用子进程。AFAIK没有等待非子进程的标准方法。尚不清楚C#函数是否可以做到这一点(取决于“关联过程”是什么)。waitwait()
库沙兰丹

我可以通过轮询来做到这一点,但那太糟糕了
Alexander Mills

它还可能会给您错误的结果。PID重用在理论上可能意味着一个进程可以使用与您正在等待的进程相同的PID来运行。在Linux(具有顺序PID)上,这不太可能,但是在像OpenBSD(随机PID分配)这样的系统上,这将是一个问题。
库沙兰丹

Answers:


21

我从这个答案中得到了我需要的东西:https : //stackoverflow.com/a/41613532/1223975

..证明使用wait <pid> 仅在该pid是当前进程的子进程时才有效

但是,以下内容适用于任何过程:

等待任何过程完成

Linux:

tail --pid=$pid -f /dev/null

达尔文(需要$pid具有打开的文件):

lsof -p $pid +r 1 &>/dev/null

超时(秒)

Linux:

timeout $timeout tail --pid=$pid -f /dev/null

达尔文(需要$pid具有打开的文件):

lsof -p $pid +r 1m%s -t | grep -qm1 $(date -v+${timeout}S +%s 2>/dev/null || echo INF)

它与Linux不相关,它是GNU tail的功能。因此,它可以在具有GNU尾部的任何系统(如GNU / Linux的系统)上运行,而不适用于非基于GNU Linux的系统。
斯特凡Chazelas

我担心在这种情况下,tail / lsof将使用轮询,至少从经验证据来看,它在MacOS上似乎是这样。
亚历山大·米尔斯

lsof + r使其处于重复模式,因此该命令每秒重复一次,因此它使用了轮询,该死的
Alexander Mills

3

您可以使用内置的bash wait

$ sleep 10 &
[2] 28751
$ wait 28751
[2]-  Done                    sleep 10
$ help wait
wait: wait [-n] [id ...]
    Wait for job completion and return exit status.

    Waits for each process identified by an ID, which may be a process ID or a
    job specification, and reports its termination status.  If ID is not
    given, waits for all currently active child processes, and the return
    status is zero.  If ID is a a job specification, waits for all processes
    in that job's pipeline.

    If the -n option is supplied, waits for the next job to terminate and
    returns its exit status.

    Exit Status:
    Returns the status of the last ID; fails if ID is invalid or an invalid
    option is given.

它使用系统调用waitpid()..

$ whatis waitpid
waitpid (2)          - wait for process to change state

非常适合我的东西,希望不要在幕后使用轮询,谢谢!
亚历山大·米尔斯

1
是的,对于我的用例而言,它是行不通的,我得到了这个错误:bash: wait: pid 47760 is not a child of this shell...回到制图板大声笑
Alexander Mills

我有答案,我刚刚发布了它
Alexander Mills

2
这将仅等待子进程,而不等待与当前进程无关的进程。
库沙兰丹

1

对于Alexander Mills重新发布的https://stackoverflow.com/a/41613532/1223975解决方案,Timeout in Seconds Darwin这是不具有GNU的类UNIX操作系统的解决方法tail。它不是特定于的Darwin,但是取决于类UNIX操作系统的年龄,所提供的命令行比必要的更为复杂,并且可能会失败:

lsof -p $pid +r 1m%s -t | grep -qm1 $(date -v+${timeout}S +%s 2>/dev/null || echo INF)

在至少一个旧的UNIX上,该lsof参数+r 1m%s失败(即使对于超级用户):

lsof: can't read kernel name list.

m%s是输出格式规范。较简单的后处理器不需要它。例如,以下命令在PID 5959上等待最多五秒钟:

lsof -p 5959 +r 1 | awk '/^=/ { if (T++ >= 5) { exit 1 } }'

在此示例中,如果PID 5959在五秒钟过去之前自行退出,${?}则为0。如果五秒钟后未${?}返回1

还可能需要明确指出,在中+r 11是轮询间隔(以秒为单位),因此可以根据情况进行更改。

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.