假设我使用 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
将接受两者。
参考