Por que colocar um trabalho em segundo plano em um script pode fazer com que o trabalho sobreviva à finalização do script e ao chamador do script?

1

Em um shell bash interativo executado dentro do lxterminal, se eu executar um job em background

$ evince &

e, em seguida, feche o shell, o trabalho em segundo plano será eliminado.

Se eu colocar o comando background em um script e executar o script em um shell bash interativo:

$ cat test.sh 
!# /bin/bash

evince &
$ ./test.sh
$

depois que o script termina, o trabalho em segundo plano ainda é executado. Mesmo depois de terminar o shell bash interativo, o trabalho em segundo plano continua em execução.

Eu me pergunto por que colocar um trabalho em segundo plano em um script e executar o script pode fazer o trabalho sobreviver tanto ao término do script quanto ao término do chamador do script? O envolvimento de um trabalho em um script é uma boa maneira de fazer o trabalho sobreviver ao término do script e ao término do shell que invoca o script?

Obrigado.

    
por Tim 05.05.2018 / 04:48

2 respostas

3

  1. Por "fechar o shell", suponho que você queira fechar o lxterminal janela. O lxterminal e o bash interativos estão conectados a uns aos outros através de um dispositivo pseudo-TTY, que é um nível de kernel construir.

    Se você fizer isso enquanto o processo filho bash interativo ainda estiver em execução, o processo lxterminal fechará seu lado do pseudo-TTY. Isso faz com que o kernel envie um sinal SIGHUP para o interativo bash .

    O capítulo SIGNALS de man bash diz:

    The shell exits by default upon receipt of a SIGHUP. Before exiting, an interactive shell resends the SIGHUP to all jobs, running or stopped. Stopped jobs are sent SIGCONT to ensure that they receive the SIGHUP.

    To prevent the shell from sending the signal to a particular job, it should be removed from the jobs table with the disown builtin (see SHELL BUILTIN COMMANDS below) or marked to not receive SIGHUP using disown -h.

    O significado pretendido do sinal SIGHUP é "a conexão com o terminal do usuário foi perdido; salve qualquer trabalho não salvo, se necessário, e então saia de forma ordenada. "(Para processos daemon, isto não é aplicável, então, para eles, o sinal é freqüentemente usado para significar "reler seus arquivos de configuração "e / ou" fecha e reabre seus arquivos de log para rotação de log ".)

    Como diz a página man, o bash interativo reenviará o SIGHUP sinal para todos os seus filhos (a menos que seja dito o contrário usando %código%). Isso é o que faz com que seu disown em segundo plano saia.

  2. Mas quando você usa um script , seu shell interativo evince s a novo processo para executar um shell para executar o script e, em seguida, o novo shell executando o script fork() s novamente para executar fork() . Depois disso, o script termina, então o shell executando o script sai.

    Neste ponto, o processo evince não terá mais um pai processo. Mas quando você olha para uma listagem evince , nunca há processo com um campo PPID vazio: é impossível para o processo não ter um pai . Então, para lidar com essa situação, o kernel atribui o PPID órfão ps -ef do processo a 1, tornando-o filho adotado do processo evince . Agora o interativo original init não sabe que a instância de bash que executou o script começou outro processo: este conhecimento morreu junto com o shell instância que executou o script.

    Como resultado, o bash interativo simplesmente não faz ideia de que existe um processo bash que pode precisar ter SIGHUP enviado para ele quando a sessão termina.

    O que você conseguiu com esse roteiro é, na verdade, o esqueleto versão de uma técnica usada quando intencionalmente daemonizing processos, conhecido como um garfo duplo . (Daemonizing a process = making completamente independente do processo e sessão que começou isso.)

    Como você viu, na prática, isso é suficiente para fazer a evince processo separado do evince interativo, mas ainda mantendo um parte de sua sessão de login da GUI. Mas se você quer um completo daemonização, há alguns outros passos que você deve fazer antes do segunda forquilha:

    • certifique-se de que a entrada padrão, a saída padrão e o erro padrão sejam redirecionados para bash
    • se algum outro descritor de arquivos estiver aberto, feche-o
    • /dev/null para que seu processo não interfira acidentalmente com o sysadmin montando / desmontando sistemas de arquivos, a menos que o processo realmente precisa acessar arquivos em um determinado sistema de arquivos
    • defina cd / explicitamente como o valor desejado / necessário
    • se o comando umask estiver disponível, você deverá usá-lo para desconectar o processo resultante do grupo de processos da sessão e torná-lo totalmente separado (ou seja, em vez de setsid no final do seu script, você pode usar evince & ).

    Veja aqui uma descrição mais detalhada de daemonizing no bash shell: link

por 05.05.2018 / 10:26
1

O assassinato do bacground mostra provavelmente algo em seu perfil de logout.

usando um script funciona porque o shell que estava executando a tarefa em segundo plano já terminou, você pode obter o mesmo efeito digitando.

( evince & )

Isso inicia um subshell, os fundos de subshell evidenciam e então saem. o evince agora é um daemon.

    
por 05.05.2018 / 10:27