Os programas executados a partir de uma sessão ssh dependem da conexão?


29

Um programa que é executado a partir de uma sessão ssh depende da conexão com o cliente? Por exemplo, quando a conexão é realmente lenta. Então, ele espera ativamente até que as coisas sejam impressas na tela?

E se isso depende da conexão, isso também acontece com a tela ou o byobu, por exemplo? Como com esses programas, os programas são mantidos em execução mesmo após a desconexão do host.


Nota: Encontrei apenas estas perguntas relacionadas:


1
Observe que, se a sua conexão for perdida, o programa continuará em execução até o tempo limite da sessão (a menos que esteja preso em uma operação de impressão), mas se a sessão terminar, o programa será encerrado normalmente.
Sebb

Respostas:


26

A saída dos programas é armazenada em buffer; portanto, se a conexão for lenta, o programa será interrompido se o buffer for preenchido.

Se você usar screen, ele também possui um buffer usado para tentar exibir em uma sessão conectada. Mas um programa conectado na sessão da tela não será interrompido se screennão for possível atualizar o terminal remoto com rapidez suficiente. Assim como quando uma conexão é perdida, o programa continua preenchendo o screensbuffer até estourar (pressionando as informações mais antigas). O que você vê entrando (e pode voltar para) depende do que está (ainda) nesse buffer. screenefetivamente desativa seu programa do seu terminal (e sua conexão SSH lenta).


9

Uma conexão SSH pode morrer prematuramente se a conexão TCP subjacente receber um pacote com o sinalizador RST . Isso pode acontecer se um lado enviar um pacote (que pode ser uma investigação periódica de manutenção da unidade SSH), mas não receber uma confirmação de TCP em um período de tempo razoável, ou se um roteador decidir que a conexão ficou inativa por muito tempo ou se um ISP está apenas sendo mau.

No modelo de terminal Unix, quando a conexão do terminal é interrompida, o driver do terminal envia um sinal HUP ao shell, cuja terminação também faz com que um SIGHUP seja enviado aos processos em execução no shell.

No FAQ do programador Unix , item 1.15:

SIGHUPé um sinal que significa, por convenção, "a linha do terminal foi desligada". Não tem nada a ver com processos-pai e geralmente é gerado pelo driver tty (e entregue ao grupo de processos em primeiro plano).

No entanto, como parte do sistema de gerenciamento de sessões, há exatamente dois casos em que SIGHUPé enviado na morte de um processo:

  • Quando o processo que morre é o líder da sessão que está conectada a um dispositivo de terminal, SIGHUPé enviado a todos os processos no grupo de processos em primeiro plano desse dispositivo de terminal.

  • Quando a morte de um processo faz com que um grupo de processo para tornar-se órfão, e um ou mais processos no grupo de órfãos está parado , então SIGHUPe SIGCONTsão enviados a todos os membros do grupo de órfãos. (Um grupo de processos órfãos é aquele em que nenhum processo no grupo tem um pai que faz parte da mesma sessão, mas não o mesmo grupo de processos.)

O manipulador de sinal padrão para SIGHUP é finalizar o processo:

Signal     Value     Action   Comment
----------------------------------------------------------------------
SIGHUP        1       Term    Hangup detected on controlling terminal
                              or death of controlling process

É possível evitar o término do processo.

  • Você pode inserir um manipulador de sinal que ignore o SIGHUP. Para fazer isso como um usuário, coloque o comando no nohup. Por exemplo:

    nohup make all &
    
  • Você pode dizer ao shell para dissociar um processo filho dele. Por exemplo, o Bash possui um disowncomando interno:

    make all
    

    CtrlZ

    bg
    disown %1
    

    Em seguida, o SIGHUP não será propagado para a criança (que não é mais uma criança).

  • Alguns programas, principalmente daemons , usarão os mecanismos acima automaticamente: um programa pode instalar um manipulador SIGHUP alternativo (usando sigaction(2)) ou pode optar por ingressar em uma nova sessão ( setsid(2)).
  • Você pode executar screenor tmux, que aloca um pseudo-TTY para executar uma sessão com um shell que não recebe o SIGHUP quando a conexão SSH morre. O SIGHUP não é retransmitido da sessão SSH para a sessão screen / tmux.

Aliás, uma maneira alternativa de lidar com conexões SSH não confiáveis ​​é usar o protocolo Mosh . O Mosh é executado em UDP, portanto, não há conexão TCP que possa ser redefinida.



1

Sim, um programa executando sobre SSH dependerá de sua saída chegar a algum lugar. Se a conexão estiver lenta, a saída deverá ser armazenada em buffer em algum lugar e os buffers não poderão ser infinitos; portanto, o programa deverá bloquear se estiver cheio.

Observe que a saída pode não necessariamente ir para um terminal: considere executar algo como

ssh user@somewhere "cat file.txt" > file.txt

Com efeito, isso copiará o arquivo. Para que isso funcione, a taxa de saída do gato deve corresponder à da conexão: deve ser óbvio que perder partes da saída do meio seria inaceitável.

A tela mudará a situação na medida em que age como um terminal e salvará o que deve ser mostrado "na janela do terminal" (mais a rolagem). Ele não precisa se lembrar de tudo o que o seu programa produz, apenas as partes que cabem na "janela" e na rolagem. Por padrão, a tela aguardará uma conexão lenta (bloqueando o programa), mas pode ser configurada para detectar uma conexão travada, definindo "nonblock on".

Na página do manual:

nonblock [on | off | numsecs]

Diga à tela como lidar com interfaces de usuário (displays) que deixam de aceitar saída. Isso pode acontecer se um usuário pressionar ^ S ou uma conexão TCP / modem for cortada, mas nenhuma interrupção for recebida. Se a opção não bloqueada estiver desativada (esse é o padrão), aguarde até que o visor reinicie para aceitar a saída. Se nonblock estiver ativado, a tela aguardará até que o tempo limite seja atingido (ativado é tratado como 1s). Se o display ainda não receber caracteres, a tela o considerará "bloqueado" e parará de enviar caracteres para ele. Se, em algum momento, reiniciar para aceitar caracteres, a tela desbloqueará a exibição e exibirá novamente o conteúdo da janela atualizada.

Uma desconexão é diferente de uma conexão lenta. O SSH comum não pode se recuperar dele automaticamente, portanto seu programa receberá um SIGHUP. Por outro lado, a tela detectará uma desconexão, desconectará e retornará ao buffer local até que a tela seja reconectada. Isso não irá bloquear o programa em execução.

(A configuração nonblock 1do seu .screenrcé importante se você executar algo como o irssi, que produzirá saída continuamente, mas ainda precisará conversar com a rede ao mesmo tempo. O bloqueio levaria à desconexão do IRC, o que é extremamente irritante ...)

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.