我想知道是否有一种方法可以监听 Linux 和 unix 中的进程 - 它何时结束以及进程(脚本)的退出代码是什么。
我不想编写一个将运行X
几秒钟并检查ps -ef | grep PID
进程是否仍然存在的脚本。我想知道是否有一种方法可以让进程在结束时通知我以及它的退出代码是什么。
答案1
一种(诚然是严厉的)方法是使用strace
:
$ strace -e trace=none -e signal=none -p 12345
将监视 PID 12345 的进程,拦截无系统调用(第一个-e
)和信号(第二个-e
)。一旦进程以常规方式退出,就会打印退出值。
如果进程被信号终止,strace 会静默退出(当使用上面给出的选项运行时)。您可以使用 例如-e signal=kill
来更改此行为。但请注意,如果程序接收并处理信号-e signal=all
,(或者等效地省略该-e signal
选项)可能会产生大量输出。
答案2
链接“通知”的执行
$ process; notify $? &
请注意,如果进程以意外方式退出,
notify
则不会执行设置陷阱
进程由不同含义的信号发出信号,并且可以做出适当的反应
#!/bin/bash process function finish { notify $? } trap finish EXIT
您不清楚您想要什么通知。本质上,它当然可以是任何敲响“钟”的东西。一为多用,例如。notify-send
从libnotify
图书馆。
$ process; notify-send "process finished with status $?" &
答案3
Bash 会为你做到这一点。当进程结束时,它会通过将控制权交还给您来通知您,并将退出状态存储在特殊变量中$?
。它看起来大致是这样的:
someprocess
echo $?
请参阅关于特殊参数的 bash 手册了解更多信息。
但我假设您在等待时想做其他工作。在 bash 中你可以这样做:
someprocess &
otherwork
wait %+
echo $?
someprocess &
将在后台启动该过程。这意味着控制权将立即返回,您可以做其他工作。在后台启动的进程在 bash 中称为作业。wait
将等待给定作业完成,然后返回该作业的退出状态。作业由 引用%n
。%+
指最后开始的作业。请参阅关于作业控制的 bash 手册了解更多信息。
如果你确实需要PID,你也可以这样做:
someprocess &
PID=$!
otherwork
wait $PID
echo $?
$!
是一个特殊变量,包含最后启动的后台进程的 PID。
答案4
您ptrace()
可以将跟踪器附加到进程(或运行新进程),设置钩with PTRACE_O_TRACEEXIT
(linux >= 2.5.60) 并休眠直到进程退出,然后 withPTRACE_GETEVENTMSG
获取退出状态。
这里有一个名为的示例实现塞子,我仅使用该attach
选项对其进行了检查,并且需要进行一些更改才能使其正常工作(最终,如果需要,我会将代码发布到某处)。