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);