如何将一个进程从终端完全分离?

如何将一个进程从终端完全分离?

我使用 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向该子进程发送 。与 不同nohupdisown被使用该流程已启动并处于后台。

不能所做的就是在启动进程后更改其 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

  1. nohup $COMMAND &
  2. $COMMAND & disown
  3. setsid command

我已经使用 2 很长时间了,但 3 也同样好用。此外,disown具有nohup标志-h,可以使用 放弃所有进程-a,并且可以使用 放弃所有正在运行的进程-ar

沉默是通过 来实现的$COMMAND &>/dev/null

希望这可以帮助!

相关内容