验证 disown 命令

验证 disown 命令

我发出该^z; bg; disown序列是为了允许我关闭一个 ssh 会话,在这个会话中我正在运行一个非常重要的长期运行的进程。此进程将状态输出写入 stderr,即使在分离后它仍继续这样做(使用 lsof 验证,s​​tderr fd 已打开以供读写)。

有没有办法确定该进程确实已被放弃(如果 shell 接收到 SIGHUP,则不会接收到 SIGHUP)?

答案1

在 Bash 中,disown其自身发出的命令将从活动作业表中删除后台(通过bg&)进程,并标记它们在注销时不会接收 SIGHUP。

您还可以将一个或多个作业传递给 disown,例如disown 1 3disown -h如果您想将作业保留在表中,但在注销时仍不发送 SIGHUP,此标志很有用。

您可以通过发出命令来查看作业表jobs。成功退出后台后,它将显示[1]+ command &。放弃作业后,该作业将不再显示在作业表中,也不会在注销时被终止。您仍然可以通过ps uxtop和其他进程查看实用程序查看进程。

当一个作业被放弃之后,你可以等待它自然终止或者通过killPID 发送信号来停止它。

因为 Bash 只是从要终止的正在运行的作业列表中删除该作业,并且终端的 stdout 和 stderr 的文件句柄仍然打开,所以您将继续接收来自该作业的输出,直到您的终端设备关闭(当您注销时)。

例子:

# we start a command in the background
$ cat /dev/urandom > test &
[1] 18533

# we see our command is still running
$ jobs
[1]+  Running                 cat /dev/urandom > test &

# we disown the backgrounded job
$ disown 1

# notice it is no longer in the job table
$ jobs

我通常只disown在运行可能长时间运行的命令(例如rsynccp)后决定需要注销而不终止它时才使用。如果您知道要运行命令并注销,则可以通过将tee其通过管道或 ing 传输到文件、使用 运行它nohup或运行它screen(这允许您重新获得命令的所有权/之后终止)来捕获输出。

例子:

# capture stdout and stderr to separate logs
cat /dev/urandom >stdout.log 2>stderr.log

# capture stdout and stderr to the same log, and display to stdout as well
cat /dev/urandom 2>&1 | tee output.log

# run a command under nohup (doesn't require a disown or job control support)
nohup cat /dev/urandom </dev/null

答案2

有没有办法确定该进程确实已被放弃(如果 shell 接收到 SIGHUP,则不会接收到 SIGHUP)?

如果最初调用该命令的 shell 仍然打开,那么您可以使用jobs@lunixbochs 提到的方法来验证该过程是否不再显示。

如果您已经关闭了 shell,那么您应该会看到父 PID (PPID) 从父进程更改为 1(init PID)。我通常使用以下命令来验证这一点ps -elf | grep <command>

例如

➜  ~ sleep infinity
^Z
[1]  + 3202480 suspended  sleep infinity

➜  ~ bg
[1]  + 3202480 continued  sleep infinity

➜  ~ ps -elf | grep sleep
0 S user    3202480 1585476  0  80   0 -  1369 ia32_s 18:23 pts/1    00:00:00 sleep infinity

➜  ~ jobs
[1]  + running    sleep infinity

➜  ~ disown %1

➜  ~ jobs

现在杀死父 shell 并查看PPID(注意现在是1):

➜  ~ ps -elf | grep sleep
0 S user    3202480 1  0  80   0 -  1369 ia32_s 18:23 pts/1    00:00:00 sleep infinity

终止作业运行:

kill -9 <PID>

相关内容