SIGTSTP(Ctrl-Z) не работает для скрипта, запущенного командой script

SIGTSTP(Ctrl-Z) не работает для скрипта, запущенного командой script

Примечание: scriptотносится к scriptкоманде, которая записывает stdin и stdout в файлы.

Я пытался запустить скрипт с помощью  scriptутилиты, чтобы сохранить вывод для последующей проверки, сохранив при этом цвета текста на терминале.

  • Когда я пытаюсь приостановить текущий скрипт с помощью Ctrl+ Z( SIGTSTP), консоль выводит сообщение ^Z, а скрипт просто не останавливается.
  • Затем я попробовал Ctrl+S ( SIGSTOP). Текущий скрипт зависает ( htopпоказывает все процессы как Zрежим), хотя и не освобождает терминал.  Ctrl+ Qвозобновляет их.

Теперь я не понимаю, почемуSIGSTOP Ctrl+ Sработает, а SIGTSTP( Ctrl+ Z) — нет.

Я знаю SIGTSTP, что может быть перехвачен, но не вижу причин делать это, и на scriptстранице руководства об этом ничего нет. Я пытался принудительно перевести интерпретатор скриптов в интерактивный режим, но результат меня еще больше запутал. Выполнение Ctrl+ Z( SIGTSTP) приостанавливает работающий скрипт, но scriptсообщает, что скрипты завершены и затем завершены, что убивает все приостановленные дочерние процессы.

Есть ли способ разрешить приостановку в такой ситуации? Также, может кто-нибудь объяснить, что именно произошло?

решение1

Как и любой другой инструмент сквозной передачи ( ssh, screen, tmux, и т. д.), scriptпереводит вызывающий терминал в режим raw, так что символы, такие как Ctrl/Z, больше не генерируют прерывания. Затем он передает эти символы дальше, и внутреннее терминальное устройство обрабатывает их «как обычно», генерируя ожидаемый сигнал. Любой процесс может выбрать перехват, SIGTSTPно не может перехватить SIGSTOP.

В этих примерах я использовал $для обозначения приглашения командной строки:

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

[1]+  Stopped                 sleep 5
$

Если вы посылаете scriptсебе SIGTSTPсигнал, он, похоже, запутается (возможно, программная ошибка?) и SIGCONTне возобновит работу. Однако отправка SIGINTили какой-либо другой завершающий сигнал возобновляется scriptдостаточно долго, чтобы сработать оригинал SIGTSTPи приостановить работу. Затем попытка возобновить scriptкоманду с помощью fgзавершает сеанс:

$ 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

В этот момент scriptполучил SIGTSTPи прекратил выполнение своего внутреннего процесса. Последующая отправка SIGCONTне имела видимых изменений.

Отправка SIGINTпривела к следующему:

Mon, 15 Apr 2
[1]+  Stopped                 script

И затем возобновляем команду:

$ fg
script

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

Мне кажется, что лучше отправить SIGSTOPв процесс внутри script. Вот еще пример:

$ 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.

Связанный контент