Linux:closuresSSH客户端后,防止后台进程停止

我正在通过SSH(腻子)在Linux机器上工作。 我需要让一个进程在夜间运行,所以我认为我可以通过在后台启动进程(在命令结尾处带有&符号)并将stdoutredirect到一个文件来实现。 令我惊讶的是,这是行不通的。 只要我closures腻子窗口,过程就停止了。

我怎样才能防止这种情况发生?

检查“ nohup ”程序。

我会build议使用GNU屏幕 。 它允许您在所有进程继续运行的情况下从服务器断开连接。 我不知道在没有它的情况下,我是如何生活的。

当会话closures时,进程收到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 blah & 

用你的进程名replace掉!

我知道这个线程是旧的,但…

守护进程? nohup的? 屏幕? (tmux ftw,屏幕是垃圾;-)

只是做一些其他应用程序从一开始就做的 – 双叉。

 # ((exec sleep 30)&) # grep PPid /proc/`pgrep sleep`/status PPid: 1 # jobs # disown bash: disown: current: no such job 

砰! 完成:-)我已经在所有types的应用程序和许多旧机器上使用过无数次。 你可以结合redirect和什么不开放你和过程之间的私人频道…

 #!/bin/bash IFS= run_in_coproc () { echo "coproc[$1] -> main" read -r; echo $REPLY } # dynamic-coprocess-generator. nice. _coproc () { local ioen=${1//[^A-Za-z0-9_]}; shift exec {i}<> <(:) {o}<> >(:) {e}<> >(:) . /dev/stdin <<COPROC "${@}" (("\$@")&) <&$i >&$o 2>&$e $n=( $o $i $e ) COPROC } # pi-rads-of-awesome? for x in {0..5}; do _coproc COPROC$x run_in_coproc $x declare -p COPROC$x done for x in COPROC{0..5}; do . /dev/stdin <<RUN read -r -u \${$x[0]}; echo \$REPLY echo "$x <- main" >&\${$x[1]} read -r -u \${$x[0]}; echo \$REPLY RUN done 

…保存为coproc.sh …

 # ./coproc.sh declare -a COPROC0='([0]="21" [1]="16" [2]="23")' declare -a COPROC1='([0]="24" [1]="19" [2]="26")' declare -a COPROC2='([0]="27" [1]="22" [2]="29")' declare -a COPROC3='([0]="30" [1]="25" [2]="32")' declare -a COPROC4='([0]="33" [1]="28" [2]="35")' declare -a COPROC5='([0]="36" [1]="31" [2]="38")' coproc[0] -> main COPROC0 <- main coproc[1] -> main COPROC1 <- main coproc[2] -> main COPROC2 <- main coproc[3] -> main COPROC3 <- main coproc[4] -> main COPROC4 <- main coproc[5] -> main COPROC5 <- main 

…在那里你去,产卵。 <(:)通过进程replace打开一个匿名pipe道,这个进程会死掉,但是由于你有一个句柄,所以pipe道就会粘住。 我通常做一个sleep 1而不是:因为它的略微活跃,我会得到一个“文件忙”的错误 – 如果一个真正的命令是跑(如command true

…“heredoc采购”:

 . /dev/stdin <<EOF [...] EOF 

…在我尝试过的每一个shell上都能正常工作,包括busybox / etc(initramfs)。 我从来没有见过它做过 – 我独立发现它,而prodding,谁知道源可以接受参数? – 但它通常作为一个更易于pipe理的formseval,如果有这样的事情…

就我个人而言,我喜欢“批处理”命令。

 $ batch > mycommand -x arg1 -y arg2 -z arg3 > ^D 

这填充到背景中,然后将结果邮寄给您。 这是cron的一部分。

正如其他人所指出的那样,为了在后台运行一个进程,以便与SSH会话断开连接,您需要让后台进程正确解除自身与控制terminal的关联 – 这是SSH会话使用的虚拟terminal。

你可以在Stevens的“Advanced Network Program,Vol 1,3rd Edn”或Rochkind的“Advanced Unix Programming”等书籍中find关于守护进程的信息。

我最近(在过去的几年里)不得不面对一个没有妥善守护自己的顽固的计划。 我最终通过创build一个通用的守护程序来处理这个问题 – 类似于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()函数的系统上,双破折号是可选的; 这是必要的(或者你必须在环境中指定POSIXLY_CORRECT)等。由于双破折号工作在任何地方,最好使用它。

如果你想要守护进程的源代码,请联系我(在Gmail点com的名字点姓氏)。

Nohup允许一个客户进程不会被杀死,如果一个父进程被杀害,当你注销时的参数。 更好的还是使用:

 nohup /bin/sh -c "echo \$\$ > $pidfile; exec $FOO_BIN $FOO_CONFIG " > /dev/null 

Nohup使得您开始的stream程免于终止,您注销后SSH会话及其subprocess将被终止。 我给出的命令为您提供了一种方法,可以将应用程序的pid存储在一个pid文件中,以便以后可以正确地将其kill掉,并允许在注销后运行该进程。

使用屏幕。 它使用起来非常简单,而且像terminal一样工作。 http://www.bangmoney.org/presentations/screen.html

如果您使用屏幕以root身份运行进程,请注意特权提升攻击的可能性。 如果您的帐户受到某种程度的损害,将会有直接的方式来接pipe整个服务器。

如果这个过程需要定期运行,并且在服务器上有足够的访问权限,那么更好的select是使用cron来运行这个工作。 你也可以使用init.d(超级守护进程)在后台启动你的进程,一旦完成就可以终止进程。

在基于Debian的系统上(在远程机器上)安装:

sudo apt-get install tmux

用法:

TMUX

运行你想要的命令

重命名会话:

然后按Ctrl + B $

设置名称

退出会话:

然后按Ctrl + B然后D

(这留下了tmux会话)。 然后,您可以注销SSH。

当你需要再次检查时,启动SSH,然后input

tmux附加session_name

它会带你回到你的tmux会话。

nohup是非常好的,如果你想logging你的细节文件。 但是当它进入后台时,如果你的脚本需要,你不能给它一个密码。 我认为你必须尝试screen 。 它的一个实用程序,你可以安装在你的Linux发行版上,例如在CentOS yum install screen上使用yum,然后通过腻子或其他软件在你的shelltypesscreen yum install screen访问你的服务器。 它将在腻子中打开屏幕[0]。 做你的工作。 您可以在同一个腻子会话中创build更多屏幕[1],屏幕[2]等。

基本命令你需要知道:

开始屏幕

屏幕


创build下一个屏幕

CTRL + A + C


转到您创build的n分机屏幕

CTRL + A + N


连接

CTRL + A + d


在工作中closures你的腻子。 下次通过腻子typeslogin时

屏幕-r

重新连接到你的屏幕,你可以看到你的程序仍然在屏幕上运行。 并退出屏幕types#exit。

欲了解更多详情,请参阅man screen

我也会去屏幕程序(我知道其他答案是屏幕,但这是一个完成)

不仅如此,&ctrl + z bg disown,nohup等等可能会给你一个令人讨厌的惊喜,即当你注销工作时仍然会被杀死(我不知道为什么,但它确实发生在我身上,而且没有打扰与它是因为我切换到使用屏幕,但我想anthonyrisinger解决scheme作为双分叉将解决这个问题),屏幕有一个主要的优势,而不仅仅是回地线:

 screen will background your process without losing interactive control to it 

顺便说一句,这是一个问题,我永远不会问首先:)我使用屏幕从任何unix做任何事情开始…我(几乎)从来没有在一个unix / linux的shell没有启animation面首先…我现在应该停下来,否则我将开始无尽的介绍,好的屏幕是什么,以及可以为你做什么…自己来看,这是值得的;)

还有开放源代码libslack包的守护进程命令。

daemon是相当可configuration的,并关心所有繁琐的守护进程的东西,如自动重启,日志logging或pidfile处理。

将此string附加到您的命令:>& – 2>& – <& – &。 >& – 表示closures标准输出。 2>& – 表示closuresstderr。 <& – 表示closuresstdin。 &手段在后台运行。 这也可以以编程的方式通过ssh启动一个作业:

 $ ssh myhost 'sleep 30 >&- 2>&- <&- &' # ssh returns right away, and your sleep job is running remotely $ 

对于大多数进程,您可以使用这个旧的Linux命令行技巧进行伪守护进程:

 # ((mycommand &)&) 

例如:

 # ((sleep 30 &)&) # exit 

然后开始一个新的terminal窗口,并:

 # ps aux | grep sleep 

将显示sleep 30仍在运行。

你所做的是以subprocess的方式启动进程,当你退出的时候,通常会触发进程退出的nohup命令不会级联到subprocess,而是作为一个孤儿进程运行。

我更喜欢这个“设置并忘记它”的方法,不需要处理nohupscreen ,tmux,I / Oredirect或者其他任何东西。

如果您也愿意运行X应用程序 – 将xpra与“屏幕”一起使用。

我用屏幕命令。 这个链接有详细的如何做到这一点

https://www.rackaid.com/blog/linux-screen-tutorial-and-how-to/#starting

接受的答案build议使用nohup 。 我宁愿build议使用pm2 。 在nohup上使用pm2有很多好处,比如让应用程序保持活动状态,维护应用程序的日志文件以及更多的其他function。 有关更多详细信息, 请查看 。

要安装pm2,你需要下载npm 。 对于基于Debian的系统

 sudo apt-get install npm 

和Redhat

 sudo yum install npm 

或者你可以按照这些说明 。 安装npm后使用它来安装pm2

 npm install pm2@latest -g 

一旦完成,你可以开始你的应用程序

 $ pm2 start app.js # Start, Daemonize and auto-restart application (Node) $ pm2 start app.py # Start, Daemonize and auto-restart application (Python) 

对于进程监视使用以下命令:

 $ pm2 list # List all processes started with PM2 $ pm2 monit # Display memory and cpu usage of each app $ pm2 show [app-name] # Show all informations about application 

使用应用程序名称或进程IDpipe理进程或一起pipe理所有进程:

 $ pm2 stop <app_name|id|'all'|json_conf> $ pm2 restart <app_name|id|'all'|json_conf> $ pm2 delete <app_name|id|'all'|json_conf> 

日志文件可以在

 $HOME/.pm2/logs #contain all applications logs 

二进制可执行文件也可以使用pm2运行。 你必须改变jason文件。 将"exec_interpreter" : "node"更改为"exec_interpreter" : "none". (请参阅属性部分 )。

 #include <stdio.h> #include <unistd.h> //No standard C library int main(void) { printf("Hello World\n"); sleep (100); printf("Hello World\n"); return 0; } 

编译上面的代码

 gcc -o hello hello.c 

并在后台运行np2

 pm2 start ./hello