Impedir que a tarefa linux atualmente em execução seja eliminada após o logout do SSH

18

Eu tenho uma tarefa computacional em execução por alguns dias em um servidor Linux via conexão SSH. Como não está em segundo plano, a conexão SSH está em espera da tarefa.

Quero reiniciar a máquina local (não o servidor) a partir da qual abri a sessão ssh, mas quero manter a tarefa em execução. Isso é possível?

Todos
fonte

Respostas:

22

Se a tarefa já está lançado, já é tarde demais *para considerar soluções alternativas que inserir uma camada adicional entre a sua sshsessão e o shell de executar o comando, como screen, tmux, byobu, nohupe os gostos.

Se o seu suporte ao processo para ser colocado em segundo plano e, particularmente, não travar quando stdoute stderrsão unwritable / fechado, você pode colocá-lo em segundo plano antes de sair com ControlZe bg, em seguida, retirá-la da sua concha com o disownbuiltin.

por exemplo:

$ ssh localhost
You have new mail.
Last login: Fri Jun  6 11:26:56 2014

$ /bin/sleep 3600    


^Z[1] + Stopped                  /bin/sleep 3600
$ bg
[1] /bin/sleep 3600&
$ jobs
[1] +  Running                 /bin/sleep 3600
$ disown %1
$ exit
Connection to localhost closed.
$ ps -ef|grep sleep
jlliagre 12864     1  0 21:12 ?        00:00:00 /bin/sleep 3600
jlliagre 13056 12477  0 21:13 pts/18   00:00:00 grep sleep
$ 

*Como comentou Bob, na verdade existem várias maneiras imprudentes de reparar uma sessão tty no Linux. repty, retty , injcode e neercs . O mais avançado parece ser reptyr, mas você pode precisar de privilégios de root para permitir que o ptrace hackear seu processo.

jlliagre
fonte
Usei Ctrl + Z, o trabalho parou e foi para o segundo plano, depois executei o disowncomando. Ele retornou: bash: AVISO: Excluir parou de trabalho 1 com o grupo processo de 24876. Agora meu trabalho está listado no ps -all, mas não parecem funcionar (uso da CPU é 0%)
Ali
Parece que meu processo está parado. Eu acho que eu deveria ter fornecido proces ID com o disowncomando
Ali
@ Ali, acho que você esqueceu de executar o comando bg para retomar o trabalho suspenso.
Jason Zhu
1
@ JasonZhu Obrigado por apontar isso. Não ficou claro que o bgcomando foi necessário na primeira parte da minha resposta. Editado.
Jlliagre #
2
Se você esqueceu o comando bg e executou apenas o comando disown, poderá executar o processo novamente, com kill -CONTo mesmo procedimento que o bg faria.
kasperd
5

Uma solução é usar a tela GNU . Você pode iniciar screen, executar seu comando e desconectar com C-a d. Mais tarde, para reconectar, faça screen -re você estará de volta à sua sessão anterior.

Outros benefícios da tela são o gerenciamento de janelas (para que você possa alternar para outros shells enquanto o comando está em execução, sem precisar de uma nova conexão SSH), e permite que o comando permaneça em primeiro plano, seja na sessão atual ou posterior.

Editar: Conforme observado nos comentários, isso só funcionará se você se lembrar de iniciar screenantes de executar o comando. Se o comando já estiver em execução, você precisará da solução do @ jlliagre.

Scott Weldon
fonte
2
tmuxé outro programa como screenesse que permite que você tenha uma sessão remota que não esteja vinculada à sua conexão SSH atual.
Darth Android
2
Sua solução é ótima. No entanto, ele não se encaixa completamente na minha pergunta - perguntei sobre o processo em execução no momento, não sobre o que deve ser executado no futuro usando screen.
Ali
Ah ok. Nesse caso, acho que você precisará usar a solução do @ jlliagre. (Tanto quanto eu sei, não há uma maneira de conectar um processo já em execução para algo como screenou tmux.)
Scott Weldon
1

Uma das maneiras "padrão" de fazer isso é usar o nohupcomando incluído em coreutils:

nohup COMMAND [ARGS] &

Mas o comando redirecionará a saída ( STDOUT& STDERRAFAIK) do programa para um arquivo nohup.out, tornando-o irritante às vezes (como gerar um grande arquivo de log); portanto, você pode fazer seu próprio redirecionamento ou redirecioná-lo para / dev / null se você quiser.

wangguoqin1001
fonte
2
Leia de novo. O processo está em execução .
Lightness Races com Monica
/ envergonhado não leu com atenção. Desculpe.
precisa saber é o seguinte
Na verdade, nohuppode ser usado para isso. Basta suspender o processo em execução e enviá-lo para segundo plano ( Ctrl+ Ze executar bg) e então você poderá emitir nohup %1.
mike
0

Além disso, nohupvocê pode iniciar o processo em segundo plano usando "&" e o subshell:

Sufixe o comando com & e coloque-o entre parênteses

$ (thecommand args &)

Vamos dizer que seu processo ganha o pid 1922:

$ ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
usr      11473  2643  0 15:07 pts/1    00:00:00 bash
usr      11922     1  0 15:11 pts/1    00:00:00 thecommand

Observe que ele não está conectado ao processo de shell 11473, que era seu pai original. Portanto, se você sair ou matar o shell atual (11473), o processo 11922 continuará em execução e será desconectado dos pts.

Tente sair do shell e entre em um novo shell. Mesmo que este shell esteja conectado aos mesmos pontos, você pode ver o processo agora sem pontos:

$ ps -fp 11922
UID        PID  PPID  C STIME TTY          TIME CMD
usr      11922     1  0 15:11 ?        00:00:00 thecommand

Não sei como é chamado ou documentado no Posix, mas eu uso dessa maneira desde 1990 no bsh, ksh e agora no bash.

Por fim, você pode usar o bgcomando shell interno:

Basta iniciar o programa e se você decidir fazer uma pausa ou planejar mantê-lo em segundo plano, digite CTRL + Z:

$ thecommand
^Z
[1] Stopped          thecommand

Agora deixe-o continuar sendo executado em segundo plano:

$ bg
[1]+ thecommand &

Se você observar as informações do processo, ele ainda possui um processo pai:

$ ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
usr      12046  2643  0 15:18 pts/6    00:00:00 bash
usr      12571 12046  0 16:00 pts/6    00:00:00 thecommand
usr      12601 12046  0 16:04 pts/6    00:00:00 ps -f

Então, saia do processo atual. O processo em execução em segundo plano é desanexado do pai original e continua em execução em segundo plano:

$ exit

Entre novamente e veja as informações do processo:

$ ps -f 12571
UID        PID  PPID  C STIME TTY          TIME CMD
usr      12571     1  0 16:00 ?        00:00:00 thecommand
Luciano
fonte