如何防止在Linux中关闭SSH客户端后停止后台进程

如何防止在Linux中关闭SSH客户端后停止后台进程,linux,process,ssh,background-process,Linux,Process,Ssh,Background Process,我正在通过SSH(Putty)在Linux机器上工作。我需要让一个进程在夜间运行,所以我想我可以在后台启动该进程(在命令末尾使用一个符号)并将stdout重定向到一个文件 令我惊讶的是,这不起作用。我一关闭腻子窗口,过程就停止了 如何防止这种情况发生???查看“”程序。查看“”程序。我建议使用。它允许您在所有进程继续运行时断开与服务器的连接。在我知道它存在之前,我不知道没有它我是如何生活的 我建议使用。它允许您在所有进程继续运行时断开与服务器的连接。在我知道它存在之前,我不知道没有它我是如何生活

我正在通过SSH(Putty)在Linux机器上工作。我需要让一个进程在夜间运行,所以我想我可以在后台启动该进程(在命令末尾使用一个符号)并将stdout重定向到一个文件

令我惊讶的是,这不起作用。我一关闭腻子窗口,过程就停止了


如何防止这种情况发生???

查看“”程序。

查看“”程序。

我建议使用。它允许您在所有进程继续运行时断开与服务器的连接。在我知道它存在之前,我不知道没有它我是如何生活的

我建议使用。它允许您在所有进程继续运行时断开与服务器的连接。在我知道它存在之前,我不知道没有它我是如何生活的

使用屏幕。它的使用非常简单,就像终端的vnc一样。
使用屏幕。它的使用非常简单,就像终端的vnc一样。

当会话关闭时,进程接收到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.

当会话关闭时,进程接收到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文件中,以便稍后正确地将其终止,并允许进程在您注销后运行。

Nohup允许在父进程终止时不终止客户端进程,用于注销时的参数。更好的方法是继续使用:

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

Nohup使您启动的进程不受终止的影响,您的SSH会话及其子进程在您注销时被终止。我给出的命令为您提供了一种方法,您可以将应用程序的pid存储在pid文件中,以便稍后可以正确地终止它,并允许进程在您注销后运行。

如其他人所述,在后台运行进程,以便您可以断开与SSH会话的连接,您需要让后台进程正确地将自己与其控制终端断开关联——这是SSH会话使用的伪tty

您可以在Stevens的《高级网络程序,第1卷,第3版Edn》或Rochkind的《高级Unix编程》等书中找到有关守护进程的信息

我最近(在过去的几年中)不得不处理一个难以解决的程序,它没有正确地将自己后台化。最后,我创建了一个通用的守护程序来解决这个问题——类似于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)。由于双破折号在任何地方都有效,因此最好使用它

如果你想知道
daemonize
的源代码,你仍然可以联系我(在gmail.com上的firstname.lastname)

但是,代码现在(最终)在GitHub上的my(Stack)中可用 溢出问题)存储库中的文件
daemonize-1.10.tgz

子目录。

正如其他人所指出的,要在后台运行进程,以便可以断开与SSH会话的连接,您需要让后台进程正确地将自身与其控制终端(SSH会话使用的伪tty)断开关联

您可以在Stevens的《高级网络程序,第1卷,第3版Edn》或Rochkind的《高级Unix编程》等书中找到有关守护进程的信息

我最近(在过去的几年中)不得不处理一个难以解决的程序,它没有正确地将自己后台化。最后,我创建了一个通用的守护程序来解决这个问题——类似于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)。由于双破折号在任何地方都有效,因此最好使用它

如果你想知道
daemonize
的源代码,你仍然可以联系我(在gmail.com上的firstname.lastname)

但是,代码现在(最终)在GitHub上的my(Stack)中可用 溢出问题)存储库中的文件
daemonize-1.10.tgz

子目录。

如果使用screen以root用户身份运行进程,请注意权限提升攻击的可能性。如果您自己的帐户受到损害,将有一个直接的方式接管整个服务器


如果这个过程需要定期运行,并且您在服务器上有足够的访问权限,那么更好的选择是使用cron来运行作业。您还可以使用init.d(超级守护进程)在后台启动您的进程,它可以在完成后立即终止。

如果您使用screen以root用户身份运行进程,请注意特权提升攻击的可能性。如果您自己的帐户受到损害,将有一个直接的方式接管整个服务器

如果这个过程需要定期运行,并且您在服务器上有足够的访问权限,那么更好的选择是使用cron来运行
#!/bin/bash

IFS=

run_in_coproc () {
    echo "coproc[$1] -> main"
    read -r; echo $REPLY
}

# dynamic-coprocess-generator. nice.
_coproc () {
    local i o e n=${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 
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
. /dev/stdin <<EOF
[...]
EOF
screen will background your process without losing interactive control to it
$ ssh myhost 'sleep 30 >&- 2>&- <&- &'
# ssh returns right away, and your sleep job is running remotely
$
# ((mycommand &)&)
# ((sleep 30 &)&)
# exit
# ps aux | grep sleep
sudo apt-get install npm
sudo yum install npm
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
$ 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
#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  
pm2 start ./hello