Por que o chromium-browser é morto quando eu fecho o terminal apesar do nohup?

10

Esta pergunta é antiga e ainda não estou claro sobre o porquê.

Pergunta original em 2014:

Em uma guia do Terminal do Gnome, eu corri

$ nohup chromium-browser &

Mas quando eu fecho a guia do terminal, chromium-browser também sai. Não é nohup que deve impedir isso? Gilles disse:

nohup and disown both can be said to suppress SIGHUP, but in different ways. nohup makes the program ignore the signal initially (the program may change this). nohup also tries to arrange for the program not to have a controlling terminal, so that it won't be sent SIGHUP by the kernel when the terminal is closed. disown is purely internal to the shell; it causes the shell not to send SIGHUP when it terminates.

Então, o nohup não faz o navegador Chrome ignorar o SIGHUP?

Estou vendo isso em outros executáveis, como Emacs (modo GUI). Mas não nos xeyes.

Isso está acontecendo no Ubuntu 12.04, 32 bits, quando a pergunta foi postada.

Atualização em 2015,

Agora estou executando o Ubuntu 14.04, com google-chrome em vez de chromium-browser instalado. A mesma coisa que aconteceu com o cromo-browser antes também acontece com o google-chrome agora. nohup google-chrome 2>/dev/null & não salva o fechamento quando a guia do terminal está fechada. /usr/bin/google-chrome é um link para um script bash /opt/google/chrome/google-chrome . Por que nohup aplicado ao script bash não funciona? Como podemos fazer isso funcionar em scripts bash? E os scripts do Python?

    
por Tim 17.10.2014 / 18:36

3 respostas

10

Quando você fecha uma janela do Terminal do GNOME, um SIGHUP é enviado para o shell que estava sendo executado. O shell normalmente envia um SIGHUP para cada grupo de processos que ele sabe que criou - mesmo aqueles iniciados com nohup - e então sai. Se o shell for bash , ele ignorará o envio de um SIGHUP para qualquer grupo de processos que o usuário marcou com disown .

Executar um comando com nohup faz com que ele ignore SIGHUP, mas o processo pode mudar isso. Quando a disposição de SIGHUP para um processo é o padrão, então se ele receber um SIGHUP, o processo será encerrado.

O Linux fornece algumas ferramentas para examinar as configurações de sinal de um processo em execução.

O script de shell do navegador do cromo faz um exec do aplicativo compilado, portanto, seu ID de processo permanece o mesmo. Então, para ver suas configurações de sinal, eu corri nohup chromium-browser & e depois olhei para /proc/$!/status para ver a disposição do sinal.

SigBlk: 0000000000000000
SigIgn: 0000000000001000
SigCgt: 0000000180014003

Esses são números hexadecimais. Isso mostra que SIGHUP não é capturado e não é ignorado. Apenas o SIGPIPE (o 13º bit no SigIgn) é ignorado. Rastreei isso para o seguinte código :

// Setup signal-handling state: resanitize most signals, ignore SIGPIPE.
void SetupSignalHandlers() {
  // Sanitise our signal handling state. Signals that were ignored by our
  // parent will also be ignored by us. We also inherit our parent's sigmask.
  sigset_t empty_signal_set;
  CHECK(0 == sigemptyset(&empty_signal_set));
  CHECK(0 == sigprocmask(SIG_SETMASK, &empty_signal_set, NULL));

  struct sigaction sigact;
  memset(&sigact, 0, sizeof(sigact));
  sigact.sa_handler = SIG_DFL;
  static const int signals_to_reset[] =
      {SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, SIGFPE, SIGSEGV,
       SIGALRM, SIGTERM, SIGCHLD, SIGBUS, SIGTRAP};  // SIGPIPE is set below.
  for (unsigned i = 0; i < arraysize(signals_to_reset); i++) {
    CHECK(0 == sigaction(signals_to_reset[i], &sigact, NULL));
  }

  // Always ignore SIGPIPE.  We check the return value of write().
  CHECK(signal(SIGPIPE, SIG_IGN) != SIG_ERR);
}

Apesar do comentário, os sinais ignorados pelo pai não são ignorados. Um SIGHUP matará o cromo.

A solução alternativa é fazer o que @ xx4h indica: use o comando disown em seu bash para que, se o bash precisar sair, ele não envie SIGHUP para o grupo de processos chromium-browser . Você pode escrever uma função para fazer isso:

mychromium () { /usr/bin/chromium-browser & disown $!; }
    
por 06.04.2015 / 18:53
2

Se chromium-browser for parecido com google-chrome , acho que o problema mais provável é que chromium-browser não é chromium , mas é um invólucro que inicializa o estado e exec s chromium .

Na instalação google-chrome , o binário está localizado em /opt/google/chrome e o wrapper em /usr/bin é apenas um script de shell que configura muito ambiente relativo a xdg-* defaults e caminhos absolutos e semelhantes antes de se substituir com o binário propriamente dito.

Neste ponto, qualquer sinal que nohup tenha inicialmente ignorado em nome do script que chamou de filho deixará de ser relevante e a menos que o script wrapper tenha o cuidado de organizá-lo de outra forma (o que não é ) o ctty é herdado.

Tente file /usr/bin/chromium-browser para verificar se é o script de shell que eu acho que é. Se assim for, considere reescrevê-lo para melhor atender você.

Eu posso dizer que apenas google-chrome 2>/dev/null & o mantém aberto para mim, mas não me lembro se esse é um resultado provável das modificações que fiz no script - há mais de um ano.

    
por 02.04.2015 / 03:52
1

O cromo parece especial.

nohup chromium-browser & disown deve funcionar neste caso. Veja também: link

    
por 17.10.2014 / 21:07

Tags