SIGTSTP (Ctrl-Z) não funciona para script iniciado por comando de script

SIGTSTP (Ctrl-Z) não funciona para script iniciado por comando de script

Nota: scriptrefere-se ao scriptcomando, que registra stdin e stdout em arquivos.

Eu estava tentando executar um script com o  scriptutilitário para salvar a saída para inspeção posterior, preservando as cores do texto no terminal.

  • Quando tento suspender o script atual com Ctrl+ Z( SIGTSTP), o console é impresso ^Ze o script simplesmente não para.
  • Eu então tentei Ctrl+S ( SIGSTOP). O script atualmente em execução congela ( htopmostra todos os processos como Zmodo), embora não libere o terminal.  Ctrl+ Qos retoma.

Agora estou confuso por queSIGSTOP Ctrl+ Sfunciona, mas SIGTSTP( Ctrl+ Z) não.

Eu sei SIGTSTPque posso estar preso, mas não vejo razão para fazer isso e não há nada sobre isso na scriptpágina de manual do. Tentei forçar o interpretador de script para o modo interativo, mas o resultado me deixou mais confuso. A emissão de Ctrl+ Z( SIGTSTP) suspende o script em execução, mas scriptindica que os scripts foram concluídos e encerrados, o que elimina todos os processos filhos suspensos.

Existe uma maneira de permitir a suspensão normalmente em tal situação? Além disso, alguém pode explicar exatamente o que aconteceu?

Responder1

Assim como qualquer outra ferramenta de passagem ( ssh, screen, tmux, etc.), scriptcoloca o terminal de chamada em modo bruto para que caracteres como Ctrl/Z não gerem mais interrupções. Em seguida, ele passa esses caracteres e o dispositivo terminal interno os processa "normalmente", gerando o sinal esperado. Qualquer processo pode optar por capturar, SIGTSTPmas não pode capturar SIGSTOP.

Nestes exemplos que usei $para indicar o prompt da linha de comando:

$ script
Script started, output log file is 'typescript'.
$ sleep 5    # After starting this I hit Ctrl/Z

[1]+  Stopped                 sleep 5
$

Se você enviar scripto SIGTSTPsinal para si mesmo, ele parecerá confuso (falha de programação, talvez?) E SIGCONTnão o retomará. No entanto, o envio SIGINTou algum outro sinal de terminação é retomado scriptpor tempo suficiente para acionar o original SIGTSTPe suspender. Em seguida, tentar retomar o scriptcomando fgencerra a sessão:

$ script
Script started, output log file is 'typescript'.
$ while date; do sleep 5; done
Mon, 15 Apr 2024 14:44:42
Mon, 15 Apr 2024 14:44:47

Neste momento scriptrecebeu SIGTSTPe deixou de executar o seu processo interno. Posteriormente, o envio SIGCONTnão fez diferença visível.

O envio SIGINTresultou nisso:

Mon, 15 Apr 2
[1]+  Stopped                 script

E então retomando o comando:

$ fg
script

Session terminated, killing shell... ...killed.
Script done.

Parece-me que seria melhor enviar SIGSTOPpara o processo interno script. Aqui está outro exemplo:

$ script
Script started, output log file is 'typescript'.
$ while date; do sleep 5; done
Mon, 15 Apr 2024 14:48:31
Mon, 15 Apr 2024 14:48:36
Mon, 15 Apr 2024 14:48:41
Mon, 15 Apr 2024 14:48:46    # Here I sent SIGSTOP to the shell running the "while" loop
Mon, 15 Apr 2024 14:49:07
Mon, 15 Apr 2024 14:49:12    # Here I hit Ctrl/C to break the loop

$ exit
Script done.

informação relacionada