Какова цель отложенной приостановки (Ctrl-Y) в Bash?


30

Полная часть справочной страницы Bash, которая применима, только говорит:

Если операционная система, в которой работает bash, поддерживает управление заданиями, bash содержит средства для ее использования. Ввод символа приостановки (обычно ^ Z, Control-Z) во время выполнения процесса вызывает остановку этого процесса и возвращает управление в bash. При вводе символа отложенного приостановления (обычно ^ Y, Control-Y) процесс останавливается, когда он пытается прочитать ввод с терминала, и управление возвращается в bash. Затем пользователь может манипулировать состоянием этого задания, используя bg команду, чтобы продолжить его в фоновом режиме,fgкоманда, чтобы продолжить это на переднем плане, или команда kill, чтобы убить это. ^ Z вступает в силу немедленно, и имеет дополнительный побочный эффект, приводящий к тому, что ожидающий вывод и typeahead отбрасываются.

Я никогда не использовал Ctrl- Y; Я только что узнал об этом. Я сделал хорошо с Ctrl- Z(приостановить) только.

Я пытаюсь представить себе , что этот вариант для . Когда это будет полезно?

(Обратите внимание, что эта функция существует не во всех вариантах Unix. Она присутствует в Solaris и FreeBSD, но не в Linux. Соответствующая настройка есть stty dsusp.)

Возможно , менее субъективно: Есть ли что - нибудь , что может быть достигнуто с Ctrl- Yчто не может быть достигнуто так же легко с Ctrl- Z?


@ Жиль, хотя у FreeBSD, похоже, есть stty dsusp, мне не удалось заставить его отправлять SIGTSTP при ^ Y (я это делал в Solaris). У тебя есть?
Стефан Шазелас

Ответы:


23

Из руководства 4BSD для csh :

A ^Zвступает в силу немедленно и походит на прерывание в том, что ожидающий вывод, а непрочитанный ввод отбрасывается при вводе. Есть еще один специальный ключ, ^Yкоторый не генерирует сигнал STOP, пока программа не попытается прочитать (2) его. Это может быть полезно набирать заранее, когда вы подготовили некоторые команды для задания, которое вы хотите остановить после того, как оно прочитало их.

Таким образом, цель состоит в том, чтобы набрать несколько входных данных во время обработки первого и завершить работу после их завершения.


Это описание слегка отличается от руководства по bash. «... не генерирует сигнал СТОП , пока программа пытается не читать его. » Это звучит , как и все во входном потоке до^Y будет прочитан успешно, а затем , когда ^Yударил процесс будет остановлен. Я читаю это правильно?
Уайлдкарт

@Wildcard в моем тесте на Mac OS X, процесс останавливается до того, как read () вернется (но после вызова read (), который бы возвратил Y, выполняется), и после его возобновления он получит входные данные до ^ Y , Я думаю, поскольку это было предназначено для использования, однако, это будет использоваться в начале строки, поэтому поведение в этом случае не будет иметь значения. Я подозреваю, что в реальном коде он приостанавливается, когда ^ Y был бы скопирован в буфер чтения пользовательского процесса.
Случайный 832

Я был прав, в функции ttread исходного ядра BSD вы можете видеть это, и современный OSX
Random832

Но когда процесс возобновится, вызов будет успешным и будет содержать данные, которые вы ввели в свой терминал раньше ^Y, даже если вы отреклись от процесса и закрыли свой терминал до возобновления процесса. Правильно? ( «... после возобновления он получает данные до ^ Y». Это то, что я имел в виду; я обычно не имею дело с кодом C). :)
Wildcard

Да. И он возвращается без новой строки в конце, что необычно для чтения в каноническом режиме [похоже, если вы набрали какой-то текст, а затем нажали ^ D один раз] Я подозреваю, что они не очень задумывались об этом случае, так как он действительно предназначен для ввода в начале строки.
Random832

11

Скажем, есть цикл чтения ввода и выполнения. Может быть полезно позволить задаче завершить текущую инструкцию, которую она вычисляет, не прерывая ее, прежде чем она вернется в командную строку для новой. Таким образом, чтобы закончить цикл. Это корректно завершает цикл и предотвращает его повторный запуск, если readвремя ожидания истекло.


Но если он будет пытаться читать входные данные из терминала в любом случае, он будет останавливаться в этой точке (и ждать вашего входа), и вы можете ^Zего потом .
Wildcard

Да. Смотрите обновление.
Томаш

Проверьте еще один. @Wildcard
Томаш

1
Но если у него есть тайм-аут, разве это не закончится просто изящно, если ты не сделал ничего особенного?
Даниэль Вагнер

1
Это может. Но это может также продолжаться и делать какую-то работу по умолчанию.
Томаш

4

Я могу вспомнить один сценарий, в котором он может быть полезен, но это что-то вроде надуманного краевого случая.

Предположим, вы отлаживаете скрипт, который записывает временные файлы, которые вы хотите проанализировать, прежде чем они будут удалены, как часть процедуры очистки.

Вы можете добавить read fooкуда-нибудь после того, как файлы будут записаны (но до очистки), запустить скрипт и нажать Ctrl- по Yмере их генерации. После этого вы перейдете к приглашению со сценарием, приостановленным в фоновом режиме, чтобы сделать все, что вам нужно, и сможете fgразрешить выполнение сценария.


1
Кажется маловероятным, потому что скрипт все равно будет ждать ввода. Таким образом, вы могли бы так же легко наблюдать, как он запрашивает ввод, а затем приостанавливать его ^Z. Другими словами: после того, как вы введете текст, fgвам все равно придется дать сценарию какой-то ввод, прежде чем он продолжится. Отсюда мой вопрос; Я до сих пор не вижу смысла ^Y. (Спасибо за ответ, хотя!) :)
Wildcard

2

Единственный сценарий, который я могу придумать (и даже я не нахожу его очень убедительным), это если вы хотите использовать какой-нибудь упреждающий ввод для команды оболочки. Допустим, запущена какая-то команда, которая будет читать ввод в будущем. Затем вы можете ^ Y это, а затем сразу же введите следующую команду оболочки, которую вы хотите выполнить, когда запущенная команда приостанавливается. Я не думаю, что когда-либо действительно использовал это в течение нескольких десятилетий использования BSD Unix.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.