350 linux terminal bash shell ubuntu
我在 Ubuntu 上使用 Tilda(下拉式终端)作为我的“命令中心”——几乎就像其他人使用 GNOME Do、Quicksilver 或 Launchy 的方式一样。
但是,我正在努力解决如何将进程(例如 Firefox)与启动它的终端完全分离 - 即防止这样的(非)子进程
例如,为了在“正确的”终端窗口中启动 Vim,我尝试了一个简单的脚本,如下所示:
exec gnome-terminal -e "vim $@" &> /dev/null &
Run Code Online (Sandbox Code Playgroud)
但是,这仍然会导致污染(而且,传递文件名似乎不起作用)。
小智 402
首先; 一旦您启动了一个进程,您可以通过首先停止它(点击Ctrl- Z)然后输入bg让它在后台恢复来将它作为后台。它现在是一个“工作”,而其stdout/ stderr/stdin仍然连接到你的终端。
您可以通过在其末尾附加一个“&”来立即启动一个后台进程:
firefox &
Run Code Online (Sandbox Code Playgroud)
要在后台静音运行它,请使用以下命令:
firefox </dev/null &>/dev/null &
Run Code Online (Sandbox Code Playgroud)
一些额外的信息:
nohup是一个可以用来运行应用程序的程序,这样它的 stdout/stderr 可以被发送到一个文件,这样关闭父脚本就不会 SIGHUP 子脚本。但是,在开始应用程序之前,您需要有先见之明才能使用它。由于工作方式nohup,您不能仅将其应用于正在运行的 process。
disown是一个 bash 内置程序,它从 shell 的作业列表中删除一个 shell 作业。这基本上意味着您不能再使用fg, bg,但更重要的是,当您关闭外壳时,它不会再挂起或发送SIGHUP给那个孩子。不像nohup,disown使用后的进程已经启动,中背景。
您不能做的是在启动进程后更改其 stdout/stderr/stdin。至少不是来自外壳。如果您启动您的进程并告诉它它的标准输出是您的终端(这是您默认执行的操作),那么该进程被配置为输出到您的终端。您的 shell 与流程的 FD 设置无关,这纯粹是流程本身管理的内容。进程本身可以决定是否关闭它的 stdout/stderr/stdin,但是你不能使用你的 shell 来强制它这样做。
要管理后台进程的输出,您可以从脚本中获得很多选项,“nohup”可能是第一个想到的。但是对于您开始但忘记静音 ( firefox < /dev/null &>/dev/null &) 的交互式流程,您真的无能为力。
我建议你获得 GNU screen。使用 screen 您可以在进程的输出变得麻烦时关闭正在运行的 shell 并打开一个新的 shell ( ^Ac)。
哦,顺便说一句,不要$@在你使用它的地方使用“ ”。
$@表示, $1, $2, $3...,这会将您的命令变成:
gnome-terminal -e "vim $1" "$2" "$3" ...
Run Code Online (Sandbox Code Playgroud)
这可能不是您想要的,因为 -e 只接受一个参数。使用$1表明你的脚本只能处理一个参数。
在您提供的场景中(使用gnome-terminal -e),让多个参数正常工作真的很困难,因为-e它只需要一个参数,即一个 shell 命令字符串。您必须将您的参数编码为一个。最好和最健壮但相当笨拙的方式是这样的:
gnome-terminal -e "vim $(printf "%q " "$@")"
Run Code Online (Sandbox Code Playgroud)
小智 220
nohup cmd &
Run Code Online (Sandbox Code Playgroud)
nohup 完全分离进程(守护进程)
小智 49
阅读这些答案,我的初步印象是发行nohup <command> &就足够了。在 gnome-terminal 中运行 zsh,我发现这nohup <command> &并没有阻止我的 shell 在退出时杀死子进程。虽然nohup很有用,尤其是对于非交互式 shell,但它仅在子进程没有为SIGHUP信号重置其处理程序时才保证这种行为。
在我的情况下,nohup应该阻止挂断信号到达应用程序,但子应用程序(在本例中为 VMWare Player)正在重置其SIGHUP处理程序。因此,当终端模拟器退出时,它仍然可能会终止您的子进程。据我所知,这只能通过确保从 shell 的作业表中删除该进程来解决。如果nohup被内置的 shell 覆盖(有时是这种情况),这可能就足够了,但是,如果它不是......
disown是一个外壳内置在bash,zsh和ksh93,
<command> &
disown
Run Code Online (Sandbox Code Playgroud)
或者
<command> &; disown
Run Code Online (Sandbox Code Playgroud)
如果你喜欢单衬。这通常具有从作业表中删除子进程的理想效果。这使您可以退出终端模拟器而根本不会意外地向子进程发出信号。无论SIGHUP处理程序是什么样子,这都不应该杀死您的子进程。
在拒绝之后,该进程仍然是您的终端模拟器的子进程(pstree如果您想观看它的实际操作,请玩一下),但是在终端模拟器退出后,您应该会看到它附加到 init 进程。换句话说,一切都是它应该的样子,而且你大概希望它是这样。
如果你的 shell 不支持disown怎么办?我强烈建议切换到一个,但如果没有那个选项,你有几个选择。
screen并且tmux可以解决这个问题,但它们是重量更重的解决方案,我不喜欢为这样一个简单的任务运行它们。它们更适合您想要维护 tty 的情况,通常是在远程机器上。setopt nohup. 这可用于指定SIGHUP在 shell 退出时不应发送到作业表中的作业。您可以在退出 shell 之前应用它,也可以将它添加到 shell 配置中,就像~/.zshrc您总是希望它一样。tcshor 中做到这一点的方法csh,这有点令人不安。exec(). 这是一个非常糟糕的解决方案,但源代码应该只包含几十行。然后,您可以将命令作为命令行参数传递给 C 程序,从而避免在作业表中出现特定于进程的条目。小智 36
nohup $COMMAND &$COMMAND & disownsetsid command我已经使用 2 号很长时间了,但 3 号也同样有效。此外,disown具有nohup标志-h,可以使用 拒绝所有进程-a,并且可以使用 拒绝所有正在运行的进程-ar。
静音是由 完成的$COMMAND &>/dev/null。
希望这可以帮助!
Man*_*d3r 14
bash 最简单且唯一正确的答案:
command & disown
Run Code Online (Sandbox Code Playgroud)
您不必从终端分离进程,而是从外壳分离。
在 tcsh 中(也可能在其他 shell 中),您可以使用括号来分离进程。
比较一下:
> jobs # shows nothing
> firefox &
> jobs
[1] + Running firefox
Run Code Online (Sandbox Code Playgroud)
对此:
> jobs # shows nothing
> (firefox &)
> jobs # still shows nothing
>
Run Code Online (Sandbox Code Playgroud)
这将从工作列表中删除 firefox,但它仍然与终端相关联;如果您通过“ssh”登录到此节点,尝试注销仍会挂起 ssh 进程。
小智 8
通过子shell取消tty shell运行命令的关联,例如
(命令)&
当退出使用终端关闭但进程仍然存在时。
查看 -
(sleep 100) & exit
Run Code Online (Sandbox Code Playgroud)
打开其他终端
ps aux | grep sleep
Run Code Online (Sandbox Code Playgroud)
进程还活着。
后台和前台工作可能是每个 Unix 系统管理员应该知道的第一件事。
这是使用 bash 完成的方法:
./script.sh
# suspend process
{ctrl-Z}
# background process
bg
# list all backgrounded jobs
jobs
# bring it back to foreground
fg
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
425375 次 |
| 最近记录: |