如果我将上一项工作置于后台,为什么 disown 不会对它执行?

如果我将上一项工作置于后台,为什么 disown 不会对它执行?

假设我使用 ctrl-z 将一个进程(例如 VIM)置于后台。然后我使用以下命令启动 xterm xterm &> /dev/null &。如果我直接输入 disown,那么我将丢失我的 vim 进程。我必须输入 xterm 进程的 PID 才能放弃它。

有什么方法可以解决这个问题或者发生这种情况的原因是什么?

答案1

如何修复(简短版本)

您可以通过以下几种方式来实现:

  • %-会要求否认最后后台作业

    xterm &> /dev/null & disown %-
    
  • 相反$!,你会要求否认最后已执行作业(通过其 PID)。

    xterm &> /dev/null & disown $!
    

因此需要多写几个字符,但至少你可以选择写哪些:-)

原因

原因就在这里:当您执行一项作业并将其发送到后台时&,本质上它不会改变当前作业,而只会改变前一项作业。目前的工作仍和之前一样。

更多词语和示例

您可以使用命令检查上述内容jobs,比较在后台启动作业之前和之后的输出。

  • :假设您有几个后台进程刚从终端运行(例如使用 和 启动dolphin &kate &
    现在您启动vim并使用 暂停它 Ctrl-Z
    的输出jobs将是:

    [1]   Running                 dolphin . &
    [2]-  Running                 kate  &
    [3]+  Stopped                 vim
    

    vim是当前作业,标记为+kate是前一个,以 标记-

    确实在 bash 参考手册中,第 7.1 章[1]解释说
    “在与作业相关的输出中(例如,jobs 命令的输出),当前作业始终用‘+’标记,而前一个作业则用‘-’标记。”

  • :最后,写下你的命令xterm &> /dev/null &(不带disown)。

    询问jobs,这次它会回答:

    [1]   Running                 dolphin .
    [2]   Running                 kate 
    [3]+  Stopped                 vim
    [4]-  Running                 xterm &> /dev/null &
    

    请注意,vim仍标有 +并且xterm带有-
    最后一个带有 标记的后台作业-xterm,不再是kate &

  • 换句话说,系统就像

    • 首先运行xterm:新命令(xterm)成为当前命令和vim前一个命令。
    • 然后xterm在后台发送,控件返回到列表中的上一个(vim及其状态),该控件再次成为当前控件,并再次标记为+.xterm而是新的之前的工作并标有-
    • 最后你发现只更新了之前的工作(-)而不是当前的(+)。

由于您可以调用disown后跟作业编号或 PID,因此有两种变体

  • %-可以使用以下方式引用以前的工作%-,如果你认为在工作中也标有-

  • $!最后一个在后台运行的作业的 PID位于特殊参数中$! [2]

该命令disown将接受两者。

参考

相关内容