为什么“kill %jobnumber”对已停止的作业不起作用?

为什么“kill %jobnumber”对已停止的作业不起作用?

我在 Ubuntu 18 LTS 系统上同时运行几个任务。因此,我通过运行以下命令在这些作业之间切换:

# command &
# fg
# fg -

我有时还使用Ctrl+Z将正在运行的作业发送到后台。

假设我的列表中有 3 项工作:

# jobs
[1]+  Stopped                 nano /etc/nginx/site-available/blog.conf
[2]   Stopped                 top
[3]-  Stopped                 nano script.sh

我可以成功地在这些作业之间切换,但是当我kill在这些作业上运行命令时,作业仍然显示在列表中。没有作业被终止。为什么?

# kill %1

我再次列出,工作仍然在那里:

# jobs
[1]+  Stopped                 nano /etc/nginx/site-available/blog.conf
[2]   Stopped                 top
[3]-  Stopped                 nano script.sh

PS:我可以通过进程 ID 来终止作业,但是为什么不可以用 呢kill %1

答案1

这里有几点需要指出:

  1. kill不带任何参数SIGTERM向所需的进程或作业标识符发送信号。

  2. SIGTERM可以被接收它的进程忽略。

  3. 已停止的进程(SIGSTOP例如使用Ctrl+恢复z)无法执行任何操作(保存文件等)。

当您kill在不带参数的情况下运行一个需要特定步骤才能关闭但无法关闭(因为它已停止)的进程时,它不会响应SIGTERM并忽略它。另一方面,它SIGKILL无法被忽略,所以它会终止该进程。这就是为什么像这样的命令sleep可以用很好的方式终止kill %1,而像这样的程序nano却不能。

答案2

如果您无法通过其 PID 终止进程,那么您也无法使用其作业的标识符终止它。

要使用其作业的标识符终止进程而不保存数据、关闭会话操作等,请使用:

kill -9 %1

kill向进程发送信号编号 15 (SIGTERM),该信号可能被进程忽略,就像我们的情况一样,因为它已停止,并且可能拒绝在停止状态下监听 SIGTERM。但是信号编号 9 (SIGKILL) 是由内核发送的,它不关心进程是否能听到。它只是强制结束进程。

相关内容