![查明进程是否在后台启动或在运行中进入后台](https://linux22.com/image/217428/%E6%9F%A5%E6%98%8E%E8%BF%9B%E7%A8%8B%E6%98%AF%E5%90%A6%E5%9C%A8%E5%90%8E%E5%8F%B0%E5%90%AF%E5%8A%A8%E6%88%96%E5%9C%A8%E8%BF%90%E8%A1%8C%E4%B8%AD%E8%BF%9B%E5%85%A5%E5%90%8E%E5%8F%B0.png)
我对 Linux 特别感兴趣,但对于其他 Unices 的答案也很好:系统是否有一种方式向进程发出信号,表明它已在后台启动?换句话说,是否有一个我可以捕获的信号,或者我可以从 Bash/Perl/Python 脚本或类似脚本中检查的信号,以告诉我该脚本在启动时是否处于后台?
答案1
在这种情况下,“背景”有多种可能的含义。
这可能意味着它没有控制终端。 (例如,某些内容是从 cron、systemd 或 init 启动的)。
如果它不仅进入后台,而且从其父进程 ( getppid
) 中孤立出来,则其父进程的 pid 将为 1。无论是否有控制终端,都可能发生这种情况。
如果进程有控制终端,则它可以位于前台或后台。
如果进程位于前台,则getpgrp
和tcgetpgrp
函数将返回相同的值(假设 tcgetpgrp 被赋予控制终端的文件描述符——例如 2=stderr)。
如果一个进程在后台,getpgrp
将会tcgetpgrp
返回不同的数字。
如果进程位于前台并且停止,它将收到信号 SIGSTOP 或 SIGTSTP 之一。请注意,SIGSTOP 无法被捕获,如果您捕获 SIGTSTP,它将阻止您的作业被停止。
当您的进程从停止状态恢复时,您会收到信号 SIGCONT,之后您可以检查您是在前台还是后台。
如果一个进程位于后台并被带到前台,我认为它不会收到任何信号,但上述检查仍然有效。
如果一个进程位于后台并尝试输入或(可能)输出,您将(分别)获得 SIGTTIN 或 SIGTTOU,您可以捕获它们。
以上对于 POSIX 系统是正确的,它涵盖了 linux 和大多数 unix 系统。
请注意,如果您的程序位于管道中间,则 stdin 和 stdout 将不是控制终端(或者如果其中一个位于管道的任一端,则它不会是控制终端)。另外,stderr 也可以被重定向(但这不太可能)。您可以通过打开来获取控制终端/dev/tty
(如果没有,则会失败),但这是不可移植的。 (不知道有没有更好的办法。)