![如何将一个进程从终端完全分离?](https://linux22.com/image/1208865/%E5%A6%82%E4%BD%95%E5%B0%86%E4%B8%80%E4%B8%AA%E8%BF%9B%E7%A8%8B%E4%BB%8E%E7%BB%88%E7%AB%AF%E5%AE%8C%E5%85%A8%E5%88%86%E7%A6%BB%EF%BC%9F.png)
我使用 Ubuntu 上的 Tilda(下拉终端)作为我的“命令中心”——与其他人使用 GNOME Do、Quicksilver 或 Launchy 的方式非常相似。
然而,我正在努力解决如何将一个进程(例如 Firefox)从启动它的终端完全分离出来 - 即防止这样的(非)子进程
- 关闭原始终端时终止
- 通过 STDOUT/STDERR“污染”原始终端
例如,为了在“正确的”终端窗口中启动 Vim,我尝试了如下简单脚本:
exec gnome-terminal -e "vim $@" &> /dev/null &
然而,这仍然会造成污染(此外,传递文件名似乎不起作用)。
答案1
首先,启动一个进程后,您可以先将其停止(按Ctrl- Z),然后键入bg
以使其在后台恢复,从而使其在后台运行。现在,它已成为一项“作业”,并且其stdout
/ stderr
/stdin
仍连接到您的终端。
您可以通过在进程末尾附加“&”来立即启动该进程作为后台进程:
firefox &
要在后台静音运行它,请使用以下命令:
firefox </dev/null &>/dev/null &
一些附加信息:
nohup
是一个你可以使用的程序运行你的应用程序这样它的 stdout/stderr 就可以被发送到文件,并且关闭父脚本不会对子脚本发出 SIGHUP 信号。但是,你需要有远见,在启动应用程序之前就使用它。由于nohup
工作方式的原因,你不能只是将其应用于正在运行的进程。
disown
是 bash 内置命令,用于从 shell 的作业列表中删除 shell 作业。这基本上意味着您不能再在其上使用fg
, bg
,但更重要的是,当您关闭 shell 时,它不会再挂起或SIGHUP
向该子进程发送 。与 不同nohup
,disown
被使用后该流程已启动并处于后台。
你不能所做的就是在启动进程后更改其 stdout/stderr/stdin。至少不是从 shell 中。如果您启动进程并告诉它其 stdout 是您的终端(默认情况下您这样做),则该进程将配置为输出到您的终端。您的 shell 与进程的 FD 设置无关,这纯粹是进程本身管理的事情。进程本身可以决定是否关闭其 stdout/stderr/stdin,但您不能使用 shell 强制它这样做。
要管理后台进程的输出,脚本中有很多选项,可能首先想到的是“nohup”。但对于您启动但忘记静音的交互式进程(firefox < /dev/null &>/dev/null &
),您真的无能为力。
我推荐你使用 GNU screen
。使用 screen 时,当进程的输出变得烦人时,你可以关闭正在运行的 shell,然后打开一个新的 ( ^Ac
)。
哦,顺便说一下,不要$@
在使用它的地方使用“”。
$@
意味着,,,$1
... $2
,$3
这会将您的命令变成:
gnome-terminal -e "vim $1" "$2" "$3" ...
这可能不是你想要的,因为 -e 只需要一参数。用于$1
表明您的脚本只能处理一个参数。
在您给出的场景中(使用gnome-terminal -e
),要让多个参数正常工作确实很困难,因为-e
只接受一个参数,即 shell 命令字符串。您必须将参数编码为一个。最好、最强大但相当笨拙的方法是这样的:
gnome-terminal -e "vim $(printf "%q " "$@")"
答案2
nohup cmd &
nohup
完全分离该进程(将其设为守护进程)
答案3
如果你正在使用bash
,请尝试;参见disown [jobspec]
重击(1)。
您可以尝试的另一种方法是at now
。如果您不是超级用户,您的使用权限at
可能会受到限制。
答案4
nohup $COMMAND &
$COMMAND & disown
setsid command
我已经使用 2 很长时间了,但 3 也同样好用。此外,disown
具有nohup
标志-h
,可以使用 放弃所有进程-a
,并且可以使用 放弃所有正在运行的进程-ar
。
沉默是通过 来实现的$COMMAND &>/dev/null
。
希望这可以帮助!