Linux: Impede que um processo em segundo plano seja interrompido após o fechamento do cliente SSH

Eu estou trabalhando em uma máquina Linux através do SSH (Putty). Eu preciso deixar um processo em execução durante a noite, então eu pensei que poderia fazer isso iniciando o processo em segundo plano (com um e comercial no final do comando) e redirecionando stdout para um arquivo. Para minha surpresa, isso não funciona. Assim que fecho a janela do Putty, o processo é interrompido.

Como posso evitar que isso aconteça?

Confira o programa ” nohup “.

Eu recomendaria o uso do GNU Screen . Ele permite que você se desconecte do servidor enquanto todos os seus processos continuam sendo executados. Eu não sei como vivi sem antes que eu soubesse que existia.

Quando a session é fechada, o processo recebe o sinal SIGHUP, que aparentemente não está captando. Você pode usar o comando nohup ao ativar o processo ou o comando nohup bash disown -h após iniciar o processo para evitar que isso aconteça:

 > 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 & 

Substitua seu nome de processo por blá!

daemonize? nohup? TELA? (tmux ftw, canvas é lixo 😉

Basta fazer o que qualquer outro aplicativo fez desde o início – garfo duplo.

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

Bang! Concluído 🙂 Eu usei isso inúmeras vezes em todos os tipos de aplicativos e muitas máquinas antigas. Você pode combinar com redirecionamentos e outros itens para abrir um canal privado entre você e o processo.

Crie como coproc.sh:

 #!/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 <&$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 <&\${$x[1]} read -r -u \${$x[0]}; echo \$REPLY RUN done 

e depois

 # ./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 

E lá vai você, desovar o que quer que seja. o <(:) abre um pipe anônimo via processo de substituição, que morre, mas o pipe fica por aí porque você tem um identificador para ele. Eu geralmente faço um sleep 1 vez de : porque é um pouco atrevido, e eu recebo um erro "arquivo ocupado" - nunca acontece se um comando real for executado (por exemplo, command true )

"heredoc sourcing":

 . /dev/stdin < 

Isso funciona em todos os shell que já experimentei, incluindo o busybox / etc (initramfs). Eu nunca vi isso feito antes, eu descobri independentemente enquanto cutucava, quem sabia que a fonte poderia aceitar args? Mas muitas vezes serve como uma forma muito mais manejável de avaliação, se é que existe tal coisa.

Pessoalmente, gosto do comando ‘batch’.

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

Isso coloca tudo em segundo plano e envia os resultados para você. Faz parte do cron.

Como outros notaram, para executar um processo em segundo plano para que você possa se desconectar de sua session SSH, é necessário que o processo em segundo plano se desassocie adequadamente de seu terminal de controle – que é a pseudo-tty que a session SSH usa.

Você pode encontrar informações sobre processos de daemonização em livros como “Advanced Network Program, Vol. 1, 3rd Edn”, de Stevens, ou “Advanced Unix Programming”, de Rochkind.

Eu recentemente (nos últimos dois anos) tive que lidar com um programa recalcitrante que não se daemonizava adequadamente. Acabei lidando com isso criando um programa genérico de daemonizing – semelhante ao nohup, mas com mais controles disponíveis.

 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) 

O traço duplo é opcional em sistemas que não usam a function GNU getopt (); é necessário (ou você tem que especificar POSIXLY_CORRECT no ambiente) no Linux, etc. Como o traço duplo funciona em todos os lugares, é melhor usá-lo.

Você ainda pode entrar em contato comigo (firstname dot lastname no gmail dot com) se você quiser a fonte para daemonize .

No entanto, o código está agora (finalmente) disponível no GitHub no meu repository SOQ (Stack Overflow Questions) como arquivo daemonize-1.10.tgz no subdiretório packages .

Nohup permite que um processo cliente não seja eliminado se um processo pai for eliminado, para um argumento quando você efetuar logout. Ainda melhor ainda usar:

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

O Nohup faz com que o processo iniciado imune à finalização, que a sua session SSH e seus processos filhos, acabam com o seu logout. O comando que eu dei fornece uma maneira que você pode armazenar o pid do aplicativo em um arquivo pid para que você possa matá-lo corretamente mais tarde e permitir que o processo seja executado após você ter efetuado logout.

Use a canvas. É muito simples de usar e funciona como o vnc para terminais. http://www.bangmoney.org/presentations/screen.html

Se você usar a canvas para executar um processo como root, tenha cuidado com a possibilidade de ataques de elevação de privilégio. Se sua própria conta for comprometida de alguma forma, haverá uma maneira direta de assumir o servidor inteiro.

Se este processo precisar ser executado regularmente e você tiver access suficiente no servidor, uma opção melhor seria usar o cron para executar o job. Você também pode usar o init.d (o super daemon) para iniciar seu processo em segundo plano, e ele pode terminar assim que estiver pronto.

Em um sistema baseado no Debian (na máquina remota) Instale:

sudo apt-get install tmux

Uso:

tmux

executar comandos que você quer

Para renomear a session:

Ctrl + B e $

nome do conjunto

Para sair da session:

Ctrl + B e D

(isso deixa a session do tmux). Então, você pode sair do SSH.

Quando você precisar voltar / verificar novamente, inicie o SSH e digite

tmux append session_name

Ele irá levá-lo de volta à sua session do tmux.

nohup é muito bom se você deseja registrar seus dados em um arquivo. Mas quando vai para o fundo você não pode dar uma senha se seus scripts pedirem. Eu acho que você deve tentar a screen . é um utilitário que você pode instalar na sua distribuição linux usando o yum, por exemplo, na yum install screen CentOS yum install screen seguida, acessar seu servidor via putty ou outro software, na screen tipo de shell. Ele irá abrir a canvas [0] em massa. Você trabalha. Você pode criar mais canvas [1], canvas [2], etc na mesma session putty.

Comandos básicos que você precisa saber:

Para iniciar a canvas

canvas


Para criar a próxima canvas

ctrl + a + c


Para mover para a canvas ext criada por você

ctrl + a + n


Para escrever

ctrl + a + d


Durante o trabalho feche sua massa. E da próxima vez que você fizer o login por meio do tipo de massa

canvas -r

Para se reconectar à sua canvas, você pode ver seu processo ainda em exibição na canvas. E para sair do tipo de canvas #exit.

Para mais detalhes, veja a man screen .

Eu também iria para o programa de canvas (eu sei que outra resposta foi canvas, mas esta é uma conclusão)

não só o fato de que &, ctrl + z bg renegar, nohup, etc. pode lhe dar uma surpresa desagradável que quando você logoff trabalho ainda será morto (eu não sei porque, mas isso aconteceu comigo, e não se incomodou com ele ser porque eu mudei para usar a canvas, mas eu acho que solução anthonyrisinger como bifurcação dupla resolveria isso), também canvas tem uma grande vantagem sobre apenas back-grounding:

 screen will background your process without losing interactive control to it 

e btw, esta é uma pergunta que eu nunca faria em primeiro lugar 🙂 … eu uso canvas do meu começo de fazer qualquer coisa em qualquer unix … eu (quase) NUNCA trabalho em um shell unix / linux sem iniciar a canvas primeiro … e eu deveria parar agora, ou eu vou começar uma apresentação interminável de que canvas é boa e o que pode fazer por você … procure por você mesmo, vale a pena;)

Há também o comando daemon do pacote libslack de código aberto.

daemon é bastante configurável e se preocupa com todo o tedioso daemon, como reboot automática, registro ou manipulação de pidfile.

Anexe esta string ao seu comando:> & – 2> & – <& - &. > & – significa fechar stdout. 2> & – significa fechar stderr. <& - significa fechar stdin. & significa correr em segundo plano. Isso funciona para iniciar programaticamente um trabalho via ssh, também:

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

Para a maioria dos processos, você pode pseudo-daemonizar usando este antigo truque de linha de comando do Linux:

 # ((mycommand &)&) 

Por exemplo:

 # ((sleep 30 &)&) # exit 

Em seguida, inicie uma nova janela de terminal e:

 # ps aux | grep sleep 

Vai mostrar que o sleep 30 ainda está funcionando.

O que você fez foi iniciar o processo como filho de um filho, e quando você sai, o comando nohup que normalmente acionaria o processo para sair não cai em cascata para o neto, deixando-o como um processo órfão, ainda corrida.

Eu prefiro essa abordagem “configure e esqueça”, sem necessidade de lidar com nohup , screen , tmux, redirecionamento de E / S ou qualquer outra coisa.

Se você estiver disposto a executar aplicativos X também – use o xpra junto com a “canvas”.

Eu usei o comando screen. Este link tem detalhes sobre como fazer isso

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

Resposta aceita sugerir o uso de nohup . Eu prefiro sugerir usando pm2 . Usar pm2 em nohup tem muitas vantagens, como manter o aplicativo ativo, manter arquivos de log para aplicativos e muito mais outros resources. Para mais detalhes, verifique isso .

Para instalar o pm2, você precisa baixar o npm . Para o sistema baseado em Debian

 sudo apt-get install npm 

e para Redhat

 sudo yum install npm 

Ou você pode seguir estas instruções . Depois de instalar o npm, use-o para instalar o pm2

 npm install pm2@latest -g 

Uma vez concluído, você pode iniciar sua inscrição

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

Para monitoramento de processos, use os seguintes comandos:

 $ 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 

Gerencie os processos usando o nome do aplicativo ou o ID do processo ou gerencie todos os processos juntos:

 $ pm2 stop  $ pm2 restart  $ pm2 delete  

Arquivos de log podem ser encontrados em

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

Arquivos executáveis ​​binários também podem ser executados usando pm2. Você tem que fazer uma mudança no arquivo jason. Altere o "exec_interpreter" : "node" para "exec_interpreter" : "none". (veja a seção de atributos ).

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

Compilando o código acima

 gcc -o hello hello.c 

e executá-lo com o np2 em segundo plano

 pm2 start ./hello 

Em systemd / Linux, systemd-run é uma ótima ferramenta para iniciar processos independentes de session. Aborrecedores que vão odiar