如何运行可以在终端关闭后继续存在的命令?

Mat*_*hew 398 command-line process terminal background-process

有时我想开始一个过程并忘记它。如果我从命令行启动它,就像这样:

redshift
Run Code Online (Sandbox Code Playgroud)

我无法关闭终端,否则它会终止进程。我可以以可以关闭终端而不终止进程的方式运行命令吗?

Ste*_*n D 415

以下 2 项之一应该有效:

$ nohup redshift &
Run Code Online (Sandbox Code Playgroud)

或者

$ redshift &
$ disown
Run Code Online (Sandbox Code Playgroud)

有关其工作原理的更多信息,请参阅以下内容:

  • 此外,`redshift &!` 将立即拒绝红移。 (21认同)
  • @Michael:`;` 和 `&` 都是命令分隔符并且具有相同的优先级。唯一的区别是同步与异步执行(分别)。没有必要优先使用`&;`而不是`&`(它可以工作,但有点多余)。 (11认同)
  • 第二个(`redshift & disown`)在 Ubuntu 10.10 上为我工作。将所有内容放在一行上似乎工作正常。有什么理由我不应该这样做吗? (8认同)
  • @Matthew 第一个也应该工作正常,它只是不像第二个背景(你可能想要 `nohup redshift &` 所以它有背景)。将第二个放在一行上很好,尽管通常用`;`(`redshift &; disown`)分开 (5认同)
  • 好的答案,有人可能会补充说,重定向 stdout 和 stderr 是个好主意,这样终端就不会被调试输出发送垃圾邮件 (5认同)

Ste*_*fan 161

如果你的程序已经在运行,你可以用 暂停它Ctrl-Zbg然后用disown它把它拉到后台,就像这样:

$ sleep 1000
^Z
[1]+  Stopped                 sleep 1000
$ bg
$ disown
$ exit
Run Code Online (Sandbox Code Playgroud)

  • 在否认之后,我如何再次读取正在运行的进程的标准输出? (3认同)
  • @neckTwi,http://serverfault.com/questions/55880/moving-an-already-running-process-to-screen (2认同)
  • @nectwi `disown` 不会断开 stdout 或 stderr。但是 `nohup` 和 `>/dev/null`(断开标准输出)、`2>/dev/null`(断开标准错误)也是如此。它 (`disown`) 断开作业控制。 (2认同)
  • 对于发现这一点的其他人来说,这对我来说真的把事情搞砸了,所以要小心。Ctrl+z 可以很好地停止它,但是 bg 让它再次开始运行,现在它不会响应 Ctrl+Z 或 Ctrl+C。现在似乎根本没有办法安全退出正在运行的命令。不知道为什么,只是按照它说的做了,但无论出于什么原因“bg”将其买回运行。我无法执行下一步输入“disown”,因为输出太多,无法输入任何内容。 (2认同)
  • @JohnMellor 您可能遇到了与 ctrl-alt-delor 的评论类似的情况,其中程序确实在后台运行,但仍然将其标准输出通过管道传输到您的 shell。Ctrl + C 和 Ctrl + Z 从这里不会执行任何操作,因为实际上没有程序在前台运行。您仍然可以从这里输入命令,例如“ls”或“disown”,没有问题,只是在输出与字符混合时很难阅读您输入的内容。我刚刚在 ffmpeg 中遇到了类似的情况,但效果很好。 (2认同)

ger*_*ijk 54

@StevenD 已经发布了很好的答案,但我认为这可能会澄清一点。

该进程在终端终止时被杀死的原因是您启动的进程是终端的子进程。关闭终端后,这也会杀死这些子进程。你可以看到进程树pstree,例如kate &在 Konsole 中运行时:

init-+
     ??konsole???bash???kate???2*[{kate}]
     ?         ?      ??pstree
     ?         ??2*[{konsole}]
Run Code Online (Sandbox Code Playgroud)

要使kate进程从konsole您终止时分离,请与命令一起konsole使用nohup,如下所示:

nohup kate &
Run Code Online (Sandbox Code Playgroud)

关闭后konsolepstree将如下所示:

init-+
     |-kate---2*[{kate}]
Run Code Online (Sandbox Code Playgroud)

kate将生存。:)

一个替代方案是使用screen/ tmux/ byobu,其将保持壳运行,独立于终端的。


小智 32

您可以在终端中运行这样的过程

setsid process

这将在新会话中运行该程序。如解释http://hanoo.org/index.php?article=run-program-in-new-session-linux

  • 1) 它不会打印关于 `nohup.out` 的烦人信息。2) 它不会保留在您的 shell 的作业列表中,因此它不会混淆 `jobs` 的输出。 (2认同)
  • 这是唯一适用于在 lxterminal 中运行的脚本的解决方案,启动 pcmanfm 并退出(使用setsid,终端可以在 pcmanfm 继续运行时关闭)。太感谢了! (2认同)

daG*_*aGo 13

我更喜欢:

(应用名称 &)

例如: linux@linux-desktop:~$ (chromium-browser &)

确保在键入命令时使用括号!

  • 关闭终端将*杀死进程*,这正是 OP(和我,因此来到这里)想要避免的 (2认同)
  • 我想知道为什么这没有得到更多的支持。`nohup` 阻止任何 tty 输出,实际上我只是想将输出重定向到一个文件,它阻止了这种情况,所以这对我来说是更好的解决方案。 (2认同)

小智 12

尽管所有建议都运行良好,但我发现我的替代方法是使用screen,这是一个在屏幕上设置虚拟终端的程序。

您可以考虑从. Screen 几乎可以安装在所有 Linux 和 Unix 衍生产品上。点击+和(小写)将开始第二个会话。这将允许你通过点击来来回切换初始会话之间+和或较新的会话击中+和。您可以在一个终端中进行多达 10 个会话。我曾经在工作中开始一个会话,回家,ssh 进入我的工作机器,然后调用. 这将使您重新连接到该远程会话。screen -S session_nameCtrlACCtrlA0CtrlA1screen -d -R session_name


joz*_*yqk 8

我有一个脚本:

  • 在后台运行任意命令

  • 阻止他们被终端窗口杀死

  • 抑制他们的输出

  • 处理退出状态

我用它主要为geditevinceinkscape等所有有很多烦人的终端输出的。如果命令在之前完成TIMEOUT,则返回 nohup 的退出状态而不是零。

#!/bin/bash

TIMEOUT=0.1

#use nohup to run the command, suppressing its output and allowing the terminal to be closed
#also send nohup's output to /dev/null, supressing nohup.out
#run nohup in the background so this script doesn't block
nohup "${@}" >/dev/null 2>&1 &
NOHUP_PID=$!

#kill this script after a short time, exiting with success status - command is still running
#this is needed as there is no timeout argument for `wait` below
MY_PID=$$
trap "exit 0" SIGINT SIGTERM
sleep $TIMEOUT && kill $MY_PID 2>/dev/null & #ignore "No such process" error if this exits normally

#if the command finishes before the above timeout, everything may be just fine or there could have been an error
wait $NOHUP_PID
NOHUP_STATUS=$?
#print an error if there was any. most commonly, there was a typo in the command
[ $NOHUP_STATUS != 0 ] && echo "Error ${@}"
#return the exit status of nohup, whatever it was
exit $NOHUP_STATUS
Run Code Online (Sandbox Code Playgroud)

例子...

>>> run true && echo success || echo fail
success
>>> run false && echo success || echo fail
Error false
fail
>>> run sleep 1000 && echo success || echo fail
success
>>> run notfound && echo success || echo fail
Error notfound
fail
Run Code Online (Sandbox Code Playgroud)


w00*_*00t 8

执行所有这些操作的仅 shell 方法是关闭 stdin 和后台命令:

command <&- & 
Run Code Online (Sandbox Code Playgroud)

那么当你退出shell时它不会退出。重定向标准输出是一个不错的可选操作。

缺点是事后你不能这样做。


小智 5

您可以将进程 (PID) 设置为在注销和关闭终端会话时不接收 HUP 信号。使用以下命令:

nohup -p PID
Run Code Online (Sandbox Code Playgroud)