%20%D0%BD%D0%B5%20%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%B0%D0%B5%D1%82%20%D0%B4%D0%BB%D1%8F%20%D1%81%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D0%B0%2C%20%D0%B7%D0%B0%D0%BF%D1%83%D1%89%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE%20%D0%BA%D0%BE%D0%BC%D0%B0%D0%BD%D0%B4%D0%BE%D0%B9%20script.png)
Примечание: script
относится к script
команде, которая записывает stdin и stdout в файлы.
Я пытался запустить скрипт с помощью script
утилиты, чтобы сохранить вывод для последующей проверки, сохранив при этом цвета текста на терминале.
- Когда я пытаюсь приостановить текущий скрипт с помощью Ctrl+ Z(
SIGTSTP
), консоль выводит сообщение^Z
, а скрипт просто не останавливается. - Затем я попробовал Ctrl+S
(. Текущий скрипт зависает (SIGSTOP
)htop
показывает все процессы какZ
режим), хотя и не освобождает терминал. Ctrl+ Qвозобновляет их.
Теперь я не понимаю, почему
Ctrl+ Sработает, а SIGSTOP
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.