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

redshift


我无法关闭终端,否则它将终止进程。我可以这样运行命令,以便在不终止进程的情况下关闭终端吗?

评论

不是所有发行版上的默认安装,但屏幕是您的朋友:en.wikipedia.org/wiki/GNU_Screen

对于面临相同问题的任何人:请记住,即使您键入yourExecutable&并且输出不断出现在屏幕上,并且Ctrl + C似乎也没有停止任何操作,只是盲目地键入disown;并且即使屏幕正在滚动显示输出并且您看不到正在键入的内容,也请按Enter键。该过程将被取消,您将可以关闭终端而该过程不会终止。

您可以使用屏幕多路复用器,例如tmux。可通过ubuntu机器上的apt-get获得它

#1 楼

以下2个选项之一应该起作用:有关其工作方式的信息:


man nohup
help disown
nohup,disown和&之间的区别(请务必也阅读注释)


评论


第二个(redshift和disown)在Ubuntu 10.10上为我工作。将其全部放在一行上似乎工作正常。有什么理由我不应该这样做吗?

–马修
10 Nov 13'0:52



@Matthew第一个也应该工作正常,只是不像第二个那样背景(您可能想要nohup redshift,所以它也有背景)。将第二行放在一行上是可以的,尽管通常情况下,您可以使用; (红移&;取消)

– Michael Mrozek
10 Nov 13'3:14

@迈克尔:两个;和&是命令分隔符,并且具有相同的优先级。唯一的区别是分别是同步执行还是异步执行。无需使用&;。优先于&(它可以工作,但是有点多余)。

–克里斯·约翰森(Chris Johnsen)
2010-11-13 4:29



好的答案,可能还要补充一点,重定向stdout和stderr是一个好主意,这样终端就不会被调试输出垃圾邮件了。

–金
2010年11月13日6:22

此外,红移&!将立即取消红移。

–user26112
13年4月21日在18:30



#2 楼

如果您的程序已经在运行,则可以使用Ctrl-Z将其暂停,使用bg将其拉入后台,然后使用disown将其拉入后台,如下所示:

$ sleep 1000
^Z
[1]+  Stopped                 sleep 1000
$ bg
$ disown
$ exit


评论


断开后,如何再次读取运行过程的标准输出?

–颈部
2014年5月22日晚上10:59

@ neckTwi,serverfault.com / questions / 55880 /…

– Stefan
2014年5月22日11:23



由于某些原因,这对我不起作用(centos)

–伊恩
15年4月17日在13:42

@necktwi disown不会断开stdout或stderr的连接。但是nohup会这样做,>> / dev / null(断开标准输出),2> / dev / null(断开标准错误)也是如此。 (取消)断开作业控制。

–ctrl-alt-delor
16年7月21日在22:08

对于其他发现此问题的人,这确实让我感到困惑,因此请小心。 Ctrl + z可以很好地停止它,但是bg使它再次开始运行,现在它不会响应Ctrl + Z或Ctrl + C。现在似乎根本无法安全退出正在运行的命令。不知道为什么,只是按照它说的做,但是无论出于什么原因,bg都买回来了。我无法进行下一步的键入disown的操作,因为有太多的输出无法键入任何内容。

–约翰·梅勒(John Mellor)
17/09/20在15:47



#3 楼

@StevenD已经发布了很好的答案,但是我认为这可能可以进一步澄清它。

终止终端终止进程的原因是您启动的进程是子进程终端的。一旦关闭终端,这也会杀死这些子进程。您可以看到带有pstree的进程树,例如,在Konsole中运行kate &时:像这样的命令:

init-+
     ├─konsole─┬─bash─┬─kate───2*[{kate}]
     │         │      └─pstree
     │         └─2*[{konsole}]


关闭kate之后,konsole看起来像这样:

nohup kate &


konsole将生存。 :)

一种替代方法是使用nohup / konsole / pstree,这将使外壳独立于终端运行。

评论


我在使用disown方法时遇到了问题。目前正在为我工​​作,因此颇受好评。我也喜欢这样,因为我可以在-f nohup.out尾部查看发生了什么,但不必担心会话失败

–伊恩
15年4月17日在13:44

#4 楼

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

setsid process

这将在新的会话中运行程序。
如http://hanoo.org所述/index.php?article=在新会话Linux中运行程序

评论


您认为setid优于nohup有什么优势?

–itsbruce
2012年10月30日10:52

1)它不会显示有关nohup.out的烦人消息。 2)它不会保留在Shell的作业列表中,因此不会使作业的输出混乱。

– Mikel
2012年11月6日在22:24



这是唯一适用于在lxterminal中运行,启动pcmanfm并退出的脚本的解决方案(使用setid时,终端可以在pcmanfm继续运行时关闭)。非常感谢!

–desgua
19年5月9日在14:48

它适用于tint2,谢谢

– kokbira
19年11月29日在11:32



#5 楼

尽管所有建议都可以正常工作,但我发现我的替代方法是使用screen这个程序在屏幕上设置虚拟终端。

您可以考虑使用screen -S session_name进行启动。屏幕几乎可以安装在所有Linux和Unix派生产品上。按下Ctrl + A和(小写)C将启动第二个会话。这将允许您通过按Ctrl + A和0在初始会话之间来回切换,或者通过按Ctrl + A和1在新会话之间来回切换。一个终端中最多可以有十个会话。我曾经在工作中开始一个会话,回家,用ssh进入我的工作机,然后调用screen -d -R session_name。这将使您重新连接到该远程会话。

评论


screen -d -m命令将在已经分离的屏幕中启动它:〜#屏幕-d -m top〜#屏幕-ls屏幕上有一个屏幕:10803..Server-station(已分离)1在/root/.screen中的套接字。 〜#屏幕-x ....,您就进入了。

–亚历山大博士
19年5月15日在6:30



#6 楼

我更喜欢:

(应用程序名称&)

例如: br />

评论


关闭终端将终止进程,而这正是OP(和我,因此来到这里)想要避免的

–birgersp
16年11月14日在14:39

可能您有我在答案中使用的没有括号的提示命令,如果这样关闭终端将终止该过程,否则将不会发生。我已经编辑了上面的解决方案以使其更加清楚。

– daGo
16年11月30日在7:13

为我工作,tnx

– noadev
18年6月14日在22:14

我想知道为什么没有更多的支持。 nohup阻止了任何tty输出,而我实际上只是想将输出重定向到文件,并且这样做可以防止,所以这对我来说是更好的解决方案。

– redanimalwar
18/12/3在4:06

非常有趣。干净,不使用其他命令。它甚至可以与sudo一起很好地玩。

–brett
3月22日19:13

#7 楼

仅通过shell进行操作的方法是关闭stdin并后台执行以下命令:

command <&- & 


然后退出shell时不会退出。重定向标准输出是一个很好的可选操作。

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

评论


我在ubuntu中尝试过。杀戮终端也关闭了启动进程。知道为什么会这样吗?

– Ashok Koyi
17年11月30日在10:57

#8 楼

我有一个脚本可以执行以下操作:


在后台运行任意命令
阻止它们被终端窗口杀死
抑制它们的输出
句柄出口status

我主要将其用于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 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


#9 楼

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

nohup -p PID


#10 楼

可以说与apolinsky提供的答案类似,我在screen上使用了一个变体。 vanilla命令是这样的

screen bash -c 'long_running_command_here; echo; read -p "ALL DONE:"'


可以使用Ctrl ACtrl D断开会话,在简单情况下可以使用screen -r重新连接会话。我将其包装在名为session的脚本中,该脚本位于我的PATH中,可以方便访问:

#!/bin/bash
#
if screen -ls | awk ' ~ /^[1-9][0-9]*\.'""'/' >/dev/null
then
    echo "WARNING: session is already running (reattach with 'screen -r ')" >&2
else
    exec screen -S "" bash -c "$@; echo; echo '--------------------'; read -p 'ALL DONE (Enter to exit):'"
    echo "ERROR: 'screen' is not installed on this system" >&2
fi
exit 1


仅当您事先知道要断开程序的连接时,此方法才有效。它不提供要断开已经运行的程序的功能。

#11 楼

与之前发布的其他答案类似,由于reptyr的缘故,您可以转移一个正在运行的进程以使用“屏幕”,然后关闭终端。这篇文章中描述了这些步骤。
要采取的步骤是:


暂停该过程
在后台恢复该过程
取消该过程
启动屏幕会话
查找过程的PID
使用reptyr接管过程