我正在通过SSH (Putty)在Linux机器上工作。我需要让一个进程在夜间运行,因此我认为可以通过在后台启动该进程(在命令末尾使用&号)并将stdout重定向到一个文件来实现这一点。
令我惊讶的是,这行不通。只要我关闭Putty窗口,进程就会停止。
我怎样才能防止这种情况发生?
我正在通过SSH (Putty)在Linux机器上工作。我需要让一个进程在夜间运行,因此我认为可以通过在后台启动该进程(在命令末尾使用&号)并将stdout重定向到一个文件来实现这一点。
令我惊讶的是,这行不通。只要我关闭Putty窗口,进程就会停止。
我怎样才能防止这种情况发生?
当前回答
当会话关闭时,进程接收到SIGHUP信号,但它显然没有捕捉到这个信号。您可以在启动进程时使用nohup命令,或者在启动进程后使用bash内置命令disown -h来防止这种情况发生:
> help disown
disown: disown [-h] [-ar] [jobspec ...]
By default, removes each JOBSPEC argument from the table of active jobs.
If the -h option is given, the job is not removed from the table, but is
marked so that SIGHUP is not sent to the job if the shell receives a
SIGHUP. The -a option, when JOBSPEC is not supplied, means to remove all
jobs from the job table; the -r option means to remove only running jobs.
其他回答
如果父进程被杀死,Nohup允许不杀死客户端进程,以便在注销时进行论证。更好的用法是:
nohup /bin/sh -c "echo \$\$ > $pidfile; exec $FOO_BIN $FOO_CONFIG " > /dev/null
Nohup使您启动的进程不受终止的影响,当您退出时,SSH会话及其子进程将被终止。我给出的命令提供了一种方法,可以将应用程序的pid存储在pid文件中,以便稍后正确地终止它,并允许进程在注销后运行。
正如其他人所指出的,要在后台运行进程以便与SSH会话断开连接,您需要让后台进程正确地与它的控制终端断开关联——这是SSH会话使用的伪tty。
您可以在Stevens的“高级网络程序,第1卷,第3版”或Rochkind的“高级Unix编程”等书籍中找到有关守护进程的信息。
最近(在过去的几年里),我不得不处理一个不听话的程序,它没有正确地守护自己。最后,我创建了一个通用的daemonizing程序来解决这个问题——类似于nohup,但是有更多的控件。
Usage: daemonize [-abchptxV][-d dir][-e err][-i in][-o out][-s sigs][-k fds][-m umask] -- command [args...]
-V print version and exit
-a output files in append mode (O_APPEND)
-b both output and error go to output file
-c create output files (O_CREAT)
-d dir change to given directory
-e file error file (standard error - /dev/null)
-h print help and exit
-i file input file (standard input - /dev/null)
-k fd-list keep file descriptors listed open
-m umask set umask (octal)
-o file output file (standard output - /dev/null)
-s sig-list ignore signal numbers
-t truncate output files (O_TRUNC)
-p print daemon PID on original stdout
-x output files must be new (O_EXCL)
在没有使用GNU getopt()函数的系统上,双破折号是可选的;这在Linux等环境中是必要的(或者你必须在环境中指定POSIXLY_CORRECT)。由于双破折号在任何地方都适用,所以最好使用它。
如果你想要daemon的源代码,你仍然可以联系我(firstname . lastname at gmail . com)。
然而,代码现在(终于)在GitHub上我的SOQ(堆栈)中可用 溢出问题)存储库为文件daemonize-1.10。TGZ在 包 子目录。
我也会去屏幕程序(我知道some1其他答案是屏幕,但这是一个完成)
事实不仅是&,ctrl+z bg disown, nohup等可能会给你一个讨厌的惊喜,当你退出工作仍然会被杀死(我不知道为什么,但它确实发生在我身上,它没有打扰它,因为我切换到使用屏幕,但我猜anthonyrisinger解决方案作为双分叉将解决这个问题),屏幕也有一个主要的优势,只是背景:
screen will background your process without losing interactive control to it
顺便说一句,这是一个我一开始就不会问的问题:)…我从一开始在Unix上做任何事情就使用screen…我(几乎)从未在unix/linux shell中工作而不首先开始屏幕…我现在应该停止了,否则我将开始无休止的演示什么是好屏幕以及可以为你们做什么……自己去查吧,很值得的;)
在systemd/Linux上,systemd-run是一个很好的工具,可以启动与会话无关的进程。
对于大多数进程,您可以使用这个旧的Linux命令行技巧进行伪守护:
# ((mycommand &)&)
例如:
# ((sleep 30 &)&)
# exit
然后启动一个新的终端窗口,然后:
# ps aux | grep sleep
将显示睡眠30仍在运行。
您所做的是将该进程作为子进程的子进程启动,当您退出时,通常会触发该进程退出的nohup命令不会级联到子进程,使其成为一个孤儿进程,仍在运行。
我更喜欢这种“设置好就忘记”的方法,不需要处理nohup、screen、tmux、I/o重定向或任何类似的东西。