Mantendo um processo Linux em execução após o logout

142

Estou me conectando a uma máquina Linux através do SSH e estou tentando executar um script bash pesado que faz operações do sistema de arquivos. Espera-se que continue funcionando por horas, mas não posso deixar a sessão SSH aberta devido aos problemas de conexão com a Internet que tenho.

Duvido que a execução do script com o operador em segundo plano, o e comercial ( &), faça o truque, porque eu tentei e depois descobri que o processo não foi concluído. Como posso sair e manter o processo em execução?

doc_id
fonte

Respostas:

135

O melhor método é iniciar o processo em um multiplexador de terminal. Como alternativa, você pode fazer com que o processo não receba o sinal HUP.


Um multiplexador de terminal fornece terminais "virtuais" que funcionam independentemente do terminal "real" (na verdade, todos os terminais hoje são "virtuais", mas esse é outro tópico para outro dia). O terminal virtual continuará funcionando, mesmo que seu terminal real esteja fechado com sua sessão ssh.

Todos os processos iniciados no terminal virtual continuarão em execução com esse terminal virtual. Quando você se reconecta ao servidor, pode se reconectar ao terminal virtual e tudo será como se nada tivesse acontecido, exceto o tempo que passou.

Dois populares multiplexadores de terminal são screen e tmux .

A tela possui uma curva de aprendizado acentuada. Aqui está um bom tutorial com diagramas explicando o conceito: http://www.ibm.com/developerworks/aix/library/au-gnu_screen/


O sinal HUP (ou SIGHUP) é enviado pelo terminal para todos os seus processos filhos quando o terminal é fechado. A ação comum ao receber o SIGHUP é terminar. Assim, quando sua sessão ssh for desconectada, todos os seus processos serão encerrados. Para evitar isso, você pode fazer com que seus processos não recebam SIGHUP.

Dois métodos fáceis de fazer isso são nohupe disown.

Para obter mais informações sobre como nohupe disownfunciona, leia esta pergunta e resposta: https://unix.stackexchange.com/questions/3886/difference-between-nohup-disown-and

Nota: embora os processos continuem em execução, você não pode mais interagir com eles porque eles não estão mais conectados a nenhum terminal. Esse método é útil principalmente para processos em lote de execução longa que, uma vez iniciados, não precisam mais de nenhuma entrada do usuário.

lesmana
fonte
3
Gosto dessa resposta, pois fornece uma solução para situações interativas e não interativas. No caso interativo, screenoferece muito mais opções, mas se você estiver usando authorized_keyspara permitir que as pessoas executem um script remotamente ssh, a nohupopção é uma maneira simples e agradável de o script iniciar processos que duram mais do que a sshsessão usada para iniciá-los .
Mark Booth
1
@rahmanisback - Lembre-se de que você pode alterar sua resposta aceita a qualquer momento. Só porque até agora a resposta do EricA é votada com mais alta qualidade não significa que é a melhor resposta para você, na verdade, torná-la sua resposta aceita pode muito bem incentivar mais pessoas a votá-la como uma boa resposta.
Mark Booth
3
* tosse * tmuxisbetter * tosse *
crasic
3
tela tmux >. Experimente, você nunca voltará.
H0tw1r3
1
@TheLQ - byobu é o GNU Screen. Você ainda está usando a tela, apenas com um .screenrc altamente personalizado.
EEAA
92

Existem algumas maneiras de fazer isso, mas a que acho mais útil é usar o GNU Screen .

Depois de entrar, corra screen. Isso iniciará outro shell em execução na tela. Execute seu comando e faça um Ctrl- a d.

Isso irá "desconectá-lo" da sessão da tela. Neste ponto, você pode sair ou fazer qualquer outra coisa que desejar.

Quando você deseja se reconectar à sessão de tela, basta executar screen -RDno prompt do shell (como o mesmo usuário de uso que criou a sessão).

EEAA
fonte
6
A tela possui vários comandos, todos começando com Ctrl-a. Se você aprender apenas um extra, comece com "Ctrl-a?". Então você não aprenderá "Ctrl-a c" e "Ctrl-a n"
olafure
@olafure +1, obrigado. Parece que a tela será a minha caixa de ferramentas principal.
doc_id 15/09/11
tela tmux >. Experimente, você nunca voltará.
H0tw1r3
+1 para tmux. Desisti da tela há 5 semanas.
perfil completo de Bryan Hunt
73

Em bash, a disownpalavra-chave é perfeitamente adequada para isso. Primeiro, execute seu processo em segundo plano (use &ou ^Zdigite bg):

$ wget --quiet http://server/some_big_file.zip &
[1] 1156

Ao digitar, jobsvocê pode ver que o processo ainda pertence ao shell:

$ jobs
[1]+  Running  wget

Se você fosse desconectado nesse ponto, a tarefa em segundo plano também seria eliminada. No entanto, se você executar disown, o bash desconecta o trabalho e permite que ele continue em execução:

$ disown

Você pode confirmar isso:

$ jobs
$ logout

Você pode até combinar o &e disownna mesma linha, como:

$ wget --quiet http://server/some_big_file.zip & disown
$ logout

Isso é melhor do que rodar nohupna minha opinião porque não deixa nohup.outarquivos espalhados por todo o sistema de arquivos. Além disso, nohupdeve ser executado antes da execução do comando - disownpode ser usado se você decidir posteriormente mais tarde que deseja colocar em segundo plano e desanexar a tarefa.

Jeremy Visser
fonte
1
Essa é uma resposta muito boa, 1+. A única preferência para nohup ou Screen seria a independência do bash e pode ser usada com outro shell. Mas continuarei com sua abordagem sempre que estiver usando o bash.
doc_id 15/09/11
Sim - isso é específico do bash, pois o bash é o único shell que eu já usei. Gostaria de saber se outras conchas suportam algo semelhante (ou seja, iniciar em segundo plano sem nohup) - seria fantástico se alguém pudesse postar outras respostas para outras conchas.
Jeremy Visser
1
veja a minha resposta mostrando como fazê-lo com qualquer sh-sósia
w00t
1
+1 por poder decidir mais tarde. Neste momento, eu precisava disso. funcionou como anunciado
code_monk
37

A ferramenta nohup, disponível na maioria das caixas Linux, fará isso.

Korjavin Ivan
fonte
1
Esta é de longe a resposta mais simples. Qualquer saída de é direcionada automaticamente para nohup.out e pode ser examinada mais tarde.
Julian
3
nohup não requer o zsh.
Aaron Brown
nohup é a resposta correta, é a abreviação de no hangup.
Kinjal Dixit 15/09/11
2
o nohup é encontrado em muito mais máquinas do que na tela, então você deve saber como usá-lo.
Zenon
27

Apenas para ser completo, vou apontar o tmux , que tem a mesma idéia básica da tela:

O tmux pretende ser uma alternativa moderna, licenciada por BSD, a programas como o GNU screen. Os principais recursos incluem:

  • Uma interface de comando poderosa, consistente, bem documentada e de fácil script.
  • Uma janela pode ser dividida horizontal e verticalmente em painéis.
  • Os painéis podem ser movidos e redimensionados livremente ou organizados em layouts predefinidos.
  • Suporte para terminais UTF-8 e 256 cores.
  • Copie e cole com vários buffers.
  • Menus interativos para selecionar janelas, sessões ou clientes.
  • Altere a janela atual pesquisando texto no destino.
  • Bloqueio do terminal, manualmente ou após um tempo limite.
  • Uma base de código com licença BSD limpa, facilmente estendida e em desenvolvimento ativo.

No entanto, é aproximadamente infinitamente mais fácil procurar no Google.

Faz-tudo5
fonte
2
Usar "gnu screen"como sua consulta de pesquisa funciona muito bem.
gnur
4
+1000 para tmux!
MBq
11

A tela é um exagero apenas para manter os processos em execução quando você se desconecta.

Tente dtach :

dtach é um programa escrito em C que emula o recurso de desanexação da tela, o que permite que um programa seja executado em um ambiente protegido do terminal de controle. Por exemplo, o programa sob o controle do dtach não seria afetado pelo desligamento do terminal por algum motivo.

dtach foi escrito porque a tela não atendeu adequadamente às minhas necessidades; Eu não precisava dos recursos extras da tela, como suporte para vários terminais ou suporte à emulação de terminal. a tela também era muito grande, volumosa e tinha um código-fonte difícil de entender.

screen também interferiu no meu uso de aplicativos de tela cheia, como emacs e ircII, devido à sua interpretação excessiva do fluxo entre o programa e os terminais conectados. O dtach não possui uma camada de emulação de terminal e passa o fluxo de saída bruto do programa para os terminais conectados. O único processamento de entrada que o dtach executa é a varredura do caractere de desanexação (que sinaliza o dtach para desanexar do programa) e o processamento da chave de suspensão (que instrui o dtach a se suspender temporariamente sem afetar o programa em execução), e ambos podem desabilitado, se desejar.

Ao contrário da tela, o dtach possui recursos mínimos e é extremamente pequeno. Isso permite que o dtach seja auditado com mais facilidade por bugs e falhas de segurança e o torna acessível em ambientes onde o espaço é limitado, como em discos de resgate.

sml
fonte
Obrigado. Eu vim aqui apenas para postar sobre dtach também. Agora é meu objetivo o desapego terminal; tela MUITO demais e interfere com a entrada em um nível ridículo. A tela de fatos precisa de seu próprio termo é muito perturbadora.
macio
9

Aqui está uma maneira de daemonize qualquer processo de shell, sem necessidade de programas externos:

( while sleep 5; do date; done ) <&- >output.txt &

Quando você fecha sua sessão, o trabalho continuará sendo executado, conforme evidenciado pelo arquivo output.txt (que possui buffering, demorando um pouco para mostrar um valor diferente de zero). Não se esqueça de matar o seu emprego após o teste.

Então, tudo o que você precisa fazer é fechar o stdin e colocar em segundo plano o trabalho. Para ser realmente bom, primeiro, cd /para não se agarrar a uma montaria.

Isso funciona mesmo em sh simples no Solaris.

w00t
fonte
Interessante. Surgiram algumas questões notáveis. Percebo que você define o STDIN para nada, o -operador? Qual é a diferença entre < /dev/nulle &-? Eu acho que o STDIN (e outros STDOUT e STDERR) podem receber um arquivo < fileou um fluxo <& streamno caso de STDIN. Seria o mesmo usando < /dev/nullno seu exemplo acima? E o operador -acima se refere a um nulo como fluxo?
doc_id 16/09/11
Quando você faz x <& -, isso fecha o descritor de arquivo x. Nesse caso, não existe x, o que torna o bash padrão como 1, ou seja, entrada padrão. Se você usa </ dev / null, não está fechando o stdin, está apenas fornecendo um arquivo vazio para o programa como entrada.
w00t
1
E para ser sincero, eu realmente não sei por que isso daemoniza o que você está executando :-) Mas funciona, nós o usamos na produção. Eu o descobri enquanto brincava, esperando poder daemonizar um processo no shell sem precisar de nada de especial - então comecei fechando o stdin e isso foi o suficiente. Eu deveria ler algumas fontes de shell, mas presumo que, se você fechar o stdin e colocar em segundo plano o processo, ele também o desanexará.
w00t
2
Acho que o motivo é que um SIGHUP (o sinal real que faz com que a criança saia quando o shell morre) é acionado quando um processo pai fecha o identificador stdin do seu filho. No entanto, se stdin começar como nulo, em vez de ser fechado após o fato, não há como o pai acionar o SIGHUP. Boa descoberta, no entanto - nunca teria pensado nisso.
Jeremy Visser
@JeremyVisser que parece realmente plausível!
W00t
7

O atcomando pode ser útil para esse tipo de situação. Por exemplo, digite:

at now

E você pode inserir um comando ou uma série de comandos que serão executados. Os resultados devem ser enviados por e-mail para você, se o e-mail estiver configurado corretamente na máquina.

Em vez de now, você pode especificar uma hora opcionalmente com uma data ou uma expressão de hora como now + 15 minutes. Veja man atpara mais detalhes.

rjmunro
fonte
7

byobuno Ubuntu é um bom front-end para a tela. PressionandoCtrl - ?você obtém uma lista de todos os atalhos do teclado. Ele adiciona uma barra de status que pode ser útil para observar a carga da CPU, espaço em disco, etc. No geral, fornece uma experiência que eu descreveria como uma conexão VNC baseada em terminal.

nohup permite iniciar um trabalho em segundo plano com sua saída roteada para um arquivo de log, que sempre pode ser redirecionado para / dev / null, se não for necessário.

John Beckett
fonte