ti-enxame.com

Como posso negar um processo em execução e associá-lo a um novo shell de tela?

Eu tenho um programa em execução em um shell SSH. Quero pausá-lo e poder interromper sua execução quando voltar.

Uma maneira que pensei em fazer isso foi transferir sua propriedade para uma tela Shell, mantendo-a funcionando lá.

Existe uma maneira diferente de proceder?

164
levesque

Usar GNU screen é sua melhor aposta.

Tela inicial em execução quando você faz login pela primeira vez - eu corro screen -D -R, execute seu comando e desconecte ou suspenda-o com CTRL-Z e depois desconecte da tela pressionando CTRL-A então D.

Quando você fizer login novamente na máquina, reconecte executando screen -D -R. Você estará no mesmo Shell de antes. Você pode executar jobs para ver o processo suspenso, se tiver feito, e executar %1 (ou o respectivo número de trabalho) para o primeiro plano novamente.

88
Andrew Yochum

Você pode revogar a "propriedade" do programa no Shell com o disown interno:

# press Ctrl+Z to suspend the program
bg
disown

No entanto, isso diz apenas ao Shell para não enviar um sinal SIGHUP para o programa quando o Shell sair. O programa manterá qualquer conexão que tenha com o terminal, geralmente como fluxos de entrada, saída e erro padrão. Não há como reconectá-las a outro terminal. ( Tela funciona emulando um terminal para cada janela, para que os programas sejam anexados à janela da tela.)


É possível anexar novamente os descritores de arquivos em um arquivo diferente, anexando o programa em um depurador (ou seja, usando ptrace ) e fazendo com que ele chame open, dup e close. Existem algumas ferramentas que fazem isso; esse é um processo complicado e, às vezes, eles interrompem o processo. As possibilidades incluem (links coletados das respostas para como posso negar um processo em execução e associá-lo a um novo shell de tela? e posso Nohup/rastrear um processo já iniciado? =):

116

Para mover um processo entre terminais ou reconectar um renegado, você pode usar, por exemplo reptyr .

67
jofel

Minha solução favorita é usar tmux, você pode desanexar a sessão e reconectá-la em outro terminal.

Quando você se desconectou da sessão anterior, pode fechar o terminal com segurança; depois use tmux attach para voltar à sessão, mesmo que você tenha se desconectado.

28
daisy

Há também um pequeno utilitário chamado retty que permite anexar novamente os programas em execução a outro terminal.

21
adamg

Eu não o uso regularmente, mas neercs afirma apoiar isso. É um programa do tipo screen com diversos recursos sofisticados, como melhor gerenciamento do painel, mas o principal que ele oferece é a capacidade de importar um processo para um painel

19
Michael Mrozek

Se você quiser apenas pausá-lo e reiniciar depois, poderá usar kill com STOP ou CONT sinal.

Primeiro, descubra os processos com o PID

$ ps aux

Em seguida, envie os sinais para o PID listado no processo

$ kill -STOP <PID>

$ kill -CONT <PID>
9
yunzen

"injcode" do ThomasHabets parece ser exatamente o que eu preciso:

https://github.com/ThomasHabets/injcode

O programa injcode permite que um código arbitrário seja injetado em um processo em execução, você sabia ou não de antemão e estava executando o screen ou tmux

No README:

Exemplo 1: mova o irssi de um terminal para outro

Talvez mova para uma tela.

Primeiro inicie o irssi em um terminal.

Execute o injcode em outro terminal: $ injcode -m retty

O Irssi agora deve ser movido para o segundo terminal, incluindo um novo terminal de controle.

9
user2688272

Isso funcionou para mim:

  1. bg o processo
  2. jobs -l encontre o número do processo
  3. tmux inicie o gerenciador de janelas do Shell
  4. reptyr -L PROCESSNUMBER

reptyr 's -L foi necessário para que isso funcionasse:

-L Like '-l', but also redirect the child's stdio to the slave.

devido a este erro:

$ reptyr 30622

[-] Unable to open the tty in the child.
Unable to attach to pid 30622: Permission denied

E com -L

$ reptyr -L 30622
Opened a new pty: /dev/pts/4
1
kqw