Ctrl + c em um subprocesso está matando um processo sem backup no início do script

15

Eu não sabia se isso pertencia ao SO (como é um bug de codificação), mas pensei que vocês teriam mais conhecimento sobre as sutilezas do software usado (então talvez até o U&L possa ser considerado).

Aqui está o script de código mínimo (veja as edições para o script completo, há uma razão para eu fazer dessa maneira);

#/bin/bash
nohup {SERVERCOMMAND} > currentOutput.log 2>&1 &

less +F currentOutput.log

O que ele tenta fazer é executar um servidor em segundo plano, que gera um arquivo de log.
Então eu followque arquivo de log usando less +F. Ao sair, você deve pressionar ctrl+ cantes de pressionar Q.

O que acontece é que, quando eu ctrl+ cdentro do lesscomando (para parar tailing), de alguma forma, mata o servidor iniciado nohupno topo! Nada mais é afetado. Eu posso shift+ fcomeçar a ajustar o log novamente (que não recebe novas informações desde que o servidor foi morto) e se eu clicar Qno restante do script, ele será executado normalmente.

Você sabe por que isso acontece? Como evitá-lo / outra coisa que eu deveria estar usando?


PS
O programa do servidor pode estar ouvindo um ^C, que pode ser o problema; Existe algo que eu possa fazer para impedir isso? Por exemplo, quando apenas corro {SERVERCOMMAND}por conta própria (de maneira bloqueadora), posso pressionar ctrl+ c, o que não mata imediatamente; ele imprime Received ^C signal, shutting down(e depois se mata). Isto é o que está acontecendo quando eu ^Cno less(A última Received ^C signal, shutting downé gravado no log).


PPS
Eu tenho tentado várias coisas (nenhuma funcionou);

  • tentando desconectar o stdin do script alterando

    nohup {SERVERCOMMAND} > currentOutput.log 2>&1 &
    to
    nohup echo '' | {SERVERCOMMAND} > currentOutput.log 2>&1 &
    or
    nohup cat /dev/null/ | {SERVERCOMMAND} > currentOutput.log 2>&1 &
  • usando stty intr ^Gpara substituir o comando de interrupção, mas, em seguida, ctrl+ gfez exatamente o que ^Cestava fazendo de qualquer maneira (de modo que este pode ser um problema com o meu emulador de terminal em vez; konsole)

  • colocando o nohup& / ou a lesslinha entre parênteses (para torná-lo um subshell)

  • executando o script em xtermvez dekonsole

Hashbrown
fonte
Alguém pode ter encontrado o meu problema; I think it is due to the handling within the database software, not on the shell. Como um programa faria isso? Como, então, posso parar com isso?
Hashbrown 30/01
3
nohupimpede que o processo receba SIGHUPsinal enquanto CTRL + C envia SIGINTsinal. É por isso nohupque não tem o efeito que você esperava.
Piotr Dobrogost

Respostas:

11

Eu estava certo ao pensar que estava SIGINTsendo enviado a todos os processos quando ctrl+ c, mas fui bobo ao pensar que fazer outro processo o traria de fora do process group(veja minhas tentativas no P.P.S.).

Este é, não apenas o caso de uso exato, mas a solução correta.

Por causa de como meu script foi estruturado, a resposta não se encaixava literalmente, este é o script agora;

#/bin/bash

setsid {SERVERCOMMAND} > currentOutput.log 2>&1 &
less +F currentOutput.log

O servidor continua a saída para o arquivo de log após I ctrl+ cno less.

Obrigado pelo tempo de todos.

Hashbrown
fonte
0

Você já tentou renegar ?

  disown -h %1

ou seja qual for o seu trabalho; disown é um shell embutido, sua página de manual afirma:

renegar

renegar [-ar] [-h] [jobspec ...]

Sem opções, cada especificação de trabalho é removida da tabela de tarefas ativas. Se a opção -h' option is given, the job 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 jobspec is not present, and neither the-a 'nor -r' option is supplied, the current job is used. If no jobspec is supplied, the-a' significa remover ou marcar todos os trabalhos; a opção `-r 'sem o argumento jobspec restringe a operação aos trabalhos em execução.

EDITAR

Engraçado, sua construção funciona no meu Arch Linux:

 $ cat testm
  #!/bin/sh

  nohup /home/mario/temp/waste & 

  less +F out.log

 $ cat waste
  #!/bin/sh

  while [ 1 ]; do
    find / -print 2>1 1> out.log
  done
  $ ./testm
   nohup: appending output to nohup.out
  $ ps ax | grep waste
    19090 pts/2    S      0:00 /bin/sh /home/mario/temp/waste
    19124 pts/2    S+     0:00 grep waste]
  $

Antes do comando ps , eu tinha que rolar o arquivo out.log Ctrl+C, então q.

MariusMatutiae
fonte
sim, mas não sei como aplicá-lo. Tentei colocar a nohuplinha em uma função que por disownssi só, mas deveria ser a mesma que nohup. Eu não acho que este é um SIGHUPproblema, pois quando eu remover a lesslinha, o script termina com o servidor ainda está em execução
Hashbrown
Pls @Hashbrown ver a minha edição
MariusMatutiae
Sim, eu fiz um teste também, com um simples script bash sendo chamado em vez do executável {SERVER}. E nohup apenas funcionou bem. Veja meu comentário sobre a questão. Eu acho que é propositadamente ouvir de alguma forma. Desde a sua propriedade um (e não bem conhecido) servidor Eu não posso nem dizer o que é que alguém pode ir "oh seu fazer X, você precisa fazer Y"
Hashbrown