fechamento do processo pai (terminal) não fecha um processo filho específico

3

Sou novo no Linux e até agora entendi que, se abrirmos um novo processo por meio de um terminal gnome, por exemplo: gedit & "& para executá-lo em segundo plano", se fecharmos o terminal, o gedit também sai. Então, para evitar isso, nós rejeitamos o processo do terminal pai dando o id do processo de gedit.

Mas eu me deparei com uma peculiaridade; Se abrirmos um terminal gnome de dentro de um terminal gnome (pai) com gnome-terminal & e agora, se fecharmos o terminal pai, o terminal filho não fecha mesmo que eu não o tenha deserdado.

Por que isso? E se houver uma exceção, qual é a razão para torná-la uma exceção e onde posso encontrar o arquivo de configuração (se acessível) onde esta exceção foi mencionada?

    
por Aman 31.12.2014 / 17:38

2 respostas

5

Quando você fecha uma janela do Terminal do GNOME, o processo de shell (ou o processo de qualquer comando que você instrui o Terminal a executar) recebe o sinal SIGHUP. Um processo pode capturar SIGHUP, o que significa que uma função especificada é chamada, e a maioria das shells a captura. O Bash reagirá a um SIGHUP enviando SIGHUP para cada um de seus processos em segundo plano (exceto aqueles que foram rejeitados).

Olhando para o seu exemplo com gedit (com alguma ajuda de pstree e strace ):
Quando a janela do Terminal GNOME é fechada, o gedit é enviado SIGHUP pelo shell, e como ele não captura SIGHUP (e não o ignora), o gedit irá sair imediatamente.

─gnome-terminal(31486)─bash(31494)──gedit(31530)

[31486] getpgid(0x7b06) = 31494
[31486] kill(-31494, SIGHUP) = 0
[31494] --- SIGHUP {si_signo=SIGHUP, si_code=SI_USER, si_pid=31486, si_uid=0} ---
[31494] kill(-31530, SIGHUP) = 0
[31530] --- SIGHUP {si_signo=SIGHUP, si_code=SI_USER, si_pid=31494, si_uid=0} ---
[31530] +++ killed by SIGHUP +++
[31494] --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_KILLED, si_pid=31530, si_status=SIGHUP} ---
[31486] --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_KILLED, si_pid=31494, si_status=SIGHUP} ---

Mas quando você digita o comando gnome-terminal e existe uma janela do Terminal GNOME, por padrão o Terminal GNOME fará algo um pouco incomum: ele chamará a fábrica org.gnome.Terminal.Factory via D-Bus e sairá imediatamente; não há trabalho em segundo plano para o shell ver por mais de uma fração de segundo.

Como resultado da chamada de fábrica, a nova janela que você obtém depois de digitar gnome-terminal é gerenciada por um novo thread do mesmo processo do Terminal GNOME que está gerenciando sua janela existente. Seu primeiro shell não tem conhecimento do id do processo do segundo shell e não pode matá-lo automaticamente.

─gnome-terminal(9063)─┬─bash(39548)
  │                   └─bash(39651)
  ├─{gnome-terminal}(9068)
  └─{gnome-terminal}(9070)

Por outro lado, se você digitar gnome-terminal --disable-factory & , ele não chamará a fábrica e, em termos de processo, ela se comportará como gedit em seu exemplo.

─gnome-terminal(39817)──bash(39825)──gnome-terminal(39867)──bash(39874)
  │                                   ├─{gnome-terminal}(39868)
  │
  └─{gnome-terminal}(39819)
Fechar a primeira janela do terminal fechará as janelas do primeiro e do segundo terminal.     
por 31.12.2014 / 20:43
1

Rodando o Xfce aqui, mas o mesmo provavelmente se aplica aos terminais Gnome.

Se eu executar echo $$ nas duas janelas do terminal [EDIT: e depois executar ps faux ], vejo apenas um % processoxfce4-terminal, mas dois processos distintos bash , que têm o mesmo pai: o processo xfce4-terminal em si. Na verdade, existe apenas um processo de terminal que mostra mais de uma janela. Tenha em mente que uma janela não implica necessariamente um processo. Execute ps faux para ver por si mesmo.

    
por 31.12.2014 / 18:02