Mantenha os processos em execução no Linux depois de desconectados dos terminais, uma solução ctrl + D?

0

Durante anos, usei nohup ou screen para manter os processos em execução depois que eu me desconectei do terminal por meio do SSH. Então, fiquei chocado quando um dos meus amigos, uma mão verde no Linux ou no CS, me disse que ctrl + D (ou exit ) poderia fazer a mesma coisa, e provavelmente de uma maneira mais elegante.

Então aqui está como fazer: Primeiro, execute seu processo em segundo plano como de costume (adicionando & ou usando bg , o que for), então, quando você quiser se desconectar do terminal, use ctrl + D ou exit para sair.

Eu sei que ctrl + D ou exit são formas muito comuns de efetuar logout. Mas depois que você logar novamente, você encontrará o processo que você acabou de iniciar a execução ... Isso pode parecer difícil de acreditar e eu disse que estava chocado. Eu tentei o método em várias situações diferentes, incluindo simples scripts python de loop morto, ele realmente funcionou.

Eu tentei pesquisar algumas informações sobre isso, mas parece que todo mundo está falando sobre nohup ou screen . O método que estou falando é de conhecimento comum? É apenas um recurso específico para alguns sistemas ou ambientes? Se estiver disponível geralmente, então qual é o significado de nohup ?

    
por liwt31 13.10.2017 / 11:03

2 respostas

1

Em primeiro lugar, você só pode usar nohup ou screen se souber antes de executar o comando que precisará continuar antes de efetuar logoff.

O que acontece quando você pressiona ctrl + D é que o buffer de entrada é enviado para o processo em execução. Agora, o que acontece a seguir depende de qual aplicativo você está atualmente.

Na maioria dos emuladores e terminais de terminal (todos?), ele simplesmente sairia de você, encerrando o processo. Isso significa que se você tivesse um processo em execução em segundo plano, que não fosse nohup 'ed ou em screen session, ele morreria junto com o seu logout.

No entanto, é possível que você esteja dentro de algum aplicativo, que usando ctrl + D não está terminando, mas colocando-o em algum estado de segundo plano.

Outro pensamento é que seu amigo estava pensando em ctrl + z - isso irá pausar o processo em execução, que você pode 'desconectar' da sessão de terminal em execução usando bg e disown . Depois de fazer isso, você pode fechar seu terminal. Isso é basicamente o mesmo que usar nohup antes de executar o processo.

Você não pode "reconectar-se" a um processo como este, uma vez que foi deserdado no entanto.

    
por 13.10.2017 / 11:12
1

Ctrl + D mapeia para EOT na tabela ASCII. Em muitos casos (a maioria?) Isso é mapeado para EOF, o que implica que não há mais dados.

Para terminais (por exemplo, bash em execução com um tty como stdin ), chamar read() quando não houver entrada do usuário geralmente bloqueará ou retornará zero (nenhum dado será lido). Quando o tty " desaparece ", bash finalmente lerá um EOF, afirmando que categoricamente não há mais entrada de dados. Você pode apresentar um EOF manualmente digitando Ctrl + D .

Vale a pena notar que coisas como bash que usam readline não apresentarão o EOF a menos que a linha atual esteja vazia. Tente digitar qualquer coisa e depois pressionar Ctrl + D - nada acontecerá.

Quando bash for executado com um script como entrada (por exemplo: executando com um arquivo como stdin ), depois que o último byte for lido, read() retornará EOF. Neste ponto, o script está completo e bash sai. Este é o mesmo comportamento que o terminal.

Se você colocar um processo em segundo plano (finalizar o comando com & ou usar Ctrl + Z e bg ), você retornará a A concha. Neste ponto, matar o shell terá efeitos diferentes no processo, dependendo do que ele faz.

  • Um processo com um arquivo como stdin provavelmente continuará sendo executado, agora herdado pelo init (PID 1).
  • Um processo com um pipe de bash as stdin também continuará sendo executado ... Até que ele tente chamar read() . Nesse ponto, o read() falhará e o aplicativo absorverá o erro e continuará ou (mais provavelmente) será encerrado com um erro.

SIGHUP (também conhecido como Hang-Up) é um sinal que é dado a um processo para informar que o outra extremidade "desligou". Eu aprecio que isso pode ser um conceito arcano ... mas neste uso, ele informa o processo que o cliente SSH desconectou, ou informa um filho de bash que bash fechou, etc ...

Se um processo não tratar explicitamente SIGHUP , a ação padrão será terminá-lo. Assim, pedir a bash para não enviar um SIGHUP para um de seus filhos permitirá efetivamente que ele seja executado após a remoção do shell.

Se você quiser deixar um comando em execução em segundo plano sem colocar as bases primeiro (consulte tmux como uma versão melhorada de screen ), então você precisará declarar especificamente " eu não quero mais esse processo anexado a este shell ".

Para conseguir isso, você pode usar disown ( ref aqui , mas precisará pesquisar / scroll), que irá arrumar as coisas para você e deixar o processo em execução:

disown [-ar] [-h] [jobspec ...]

Without options, each jobspec is removed from the table of active jobs. If jobspec is not present, and neither -a nor -r is supplied, the shell's notion of the current job is used. If the -h option is given, each jobspec is not removed from the table, but is marked so that SIGHUP is not sent to the job if the shell receives a SIGHUP. If no jobspec is present, and neither the -a nor the -r option is supplied, the current job is used. If no jobspec is supplied, the -a option means to remove or mark all jobs; the -r option without a jobspec argument restricts operation to running jobs. The return value is 0 unless a jobspec does not specify a valid job.

As coisas provavelmente darão errado se o processo tentar read() de stdin , portanto, se você quiser explicitamente desconectar um processo em execução, certifique-se de que stdin esteja apontando para /dev/null ou similar, ou use tmux antes do tempo.

NOTA: escrever para stdout ou stderr provavelmente será tão mortal quanto tentar ler stdin nesses casos ... SIGPIPE ahoy.

É possível, com o auxílio de ferramentas, redirecionar stdin , stdout , stderr de um processo em execução, tornando muito mais seguro sair usando as chamadas do sistema de depuração (você pode ter dificuldade, veja isto ). Eu estou lutando para lembrar o nome de um aplicativo C que eu usei no passado, mas um pouco de remexendo apareceu dupx que também pode ajudar, ou pelo menos ser interessante investigar.

Ambos operam fundamentalmente fazendo o seguinte dentro do processo de destino:

fd = open("/dev/null", O_RDONLY);
dup2(fd, stdin);
close(fd);

fd = open("/dev/null", O_WRONLY);
dup2(fd, stdout);
dup2(fd, stderr);
close(fd);
    
por 13.10.2017 / 11:38