Я написал сценарий оболочки для тестирования API, который копирует файлы и отображает их прогресс после каждого.
Между каждой копией существует двухсекундный сон, поэтому я хотел бы добавить возможность нажатия любой клавиши, чтобы приостановить выполнение сценария, чтобы провести более глубокое тестирование. Затем нажмите любую клавишу для возобновления.
Как я могу добавить это как можно меньше строк?
shell-script
blarg
источник
источник
sleep 10; notify-send hello
и нажму CTRL + Z, чтобы остановиться,notify-send hello
начните выполнение. если вторая команда выполняется, почему первый процесс останавливается? после этого, если набрать,fg
я не вижу ничего, что происходит, что очевидно, поскольку вторая команда уже выполненаcmd; cmd; cmd;
похоже на письмоcmd <newline> cmd <newline> ...
. В качестве альтернативы сценарию, который вы можете написать( cmd; cmd; cmd; )
, он будет вести себя как сценарий, как основа подоболочки, сгенерированной(
sleep 10
. когда я нажимаю CTRL + Z через 3 секунды и возобновляюсь через несколько секунд, и замечаю, что команда сна умерла менее чем за 7 секунд. что противоположно тому, что вы сказали, поскольку команда nevers останавливается, она просто работает в фоновом режиме.strace
d вsleep
команду и узнал, что системный вызов используетсяnanosleep()
. Кажется, это определенное поведение системного вызоваnanosleep
.restart_syscall()
перезапускает прерванный системный вызов с аргументом времени, который соответствующим образом настроен для учета времени, которое уже прошло (включая время, когда процесс был остановлен сигналом). Прочтите эту man- страницуfg %1
или на заднем плане (например:)bg %1
. (если задания выдают только 1 номер, то есть только 1 приостановленный процесс, как показано в примере с хаосом: только[1]+ stopped sleep 10
, вы можете опустить%n
деталь. Если есть несколько фоновых процессов (запущенных или остановленных), вам нужно назначить тот, который вы хотите с:%n
(например,fg %2
чтобы% 2 возобновилось на переднем плане))Если вы хотите просто приостановить выполнение сценария, оставаясь внутри сценария, вы можете использовать чтение вместо сна.
Ты можешь использовать
read -t
установить тайм-аут чтенияread -n
для чтения одного символа (фактически просто нажмите любую клавишу), чтобы продолжить сценарийПоскольку вы не предоставили никакого кода, ниже приведен пример того, как его можно использовать.
Если нажать q, то
read -n1
сценарий не будет продолжаться до тех пор, пока не будет нажата клавиша.Когда клавиша нажата, проверка сбрасывается, и сценарий продолжает цикл как обычно.
Вы также можете добавить
stty -echo
в начало раздела иstty echo
в конец, чтобы не допустить путаницы при наборе текстаисточник
С
dd
его помощью можно надежно прочитать один байт из файла. С помощьюstty
вы можете установитьmin
количество байтов, чтобы квалифицировать чтение терминала иtime
выход в десятых долях секунды. Объедините эти два, и вы можете обойтись без нихsleep
, я думаю, и просто дайте таймауту чтения терминала сделать работу за вас:Это небольшой пример
while
цикла, который я смоделировал для вас, чтобы попробовать. Каждые две секундыdd
истекает время попытки чтенияstdin
- перенаправлено с/dev/tty
- иwhile
циклы цикла. Это илиdd
не время ожидания, потому что вы нажимаете клавишу - в этом случае вызывается интерактивная оболочка.Вот тестовый прогон - числа, напечатанные в заголовке каждой строки, являются значением переменной оболочки
$SECONDS
:источник
stty sane
после изменения настроек STTY, я могу ошибаться, но не похоже, что вы их сбросили где-нибудь?s=$(stty -g </dev/tty)
. Сразу после звонкаdd
я потом восстановил с помощьюstty "$s"
. Состояние терминала не заботится о подоболочках, поэтому эти настройки остаются неизменными независимо от родительской оболочки.stty sane
это не обязательно то, что вы хотите сделать - лучше восстановить состояние так, как вы его нашли, чем предполагать, что состояние былоsane
в тот момент. Если бы я не восстановил это, этиecho
были бы повсюду. Отчасти это понятно, поэтому я пришел так поздно - ваш ответ не был здесь, когда я начал тестирование.