Я могу объяснить это, но я не знаю, как это исправить. Это беспокоило меня годами тоже. Не менее 20 Это не единственная ошибка в какой-либо конкретной программе, а условие состязания между 3 программами, которые по отдельности ведут себя как задумано, и достаточно общее, что оно применимо ко многим комбинациям программ.
Когда вы читаете ^Z
во время чтения страницы руководства, вы отправляете SIGTSTP
в группу процессов переднего плана, которая состоит из процесса man
и его потомков. Пейджер (less
) является одним из тех потомков.
man
немедленно отстранен, но less
нет. У него есть обработчик сигнала. И для этого есть веская причина. Он изменил режим tty (так что он может читать символы, как только они набраны), и он хочет восстановить исходный режим и привести в порядок экран перед тем, как отказаться от контроля. Так оно и есть.
Между тем (это редкое слово) оболочка заметила, что процесс man
остановлен. И вот плохая часть: оболочка понятия не имеет, что существует less
процесс. Unix-процессы, как правило, не имеют возможности узнать о своих внуках. Таким образом, с точки зрения оболочки, работа прекратилась, хотя на самом деле less
еще не закончил уборку.
Обрабатывая неполную информацию, оболочка возвращается на передний план, печатает уведомление о задании, устанавливает режим tty для собственного редактора строк и печатает подсказку. Но это гонки с less
, которые все еще пытаются привести в порядок. Пока оболочка печатает подсказку и настраивает режим atty, меньше занята перемещением курсора и очисткой нижней строки экрана (где было less
подсказки).
Поскольку это гонка, есть много возможных результатов, в зависимости от порядка операций, но наиболее раздражающим является следующее:
- оболочка печатает уведомление о задании, устанавливает режим tty для своего редактора строк и печатает приглашение.
less
перемещает курсор в нижний левый угол, очищает нижнюю строку (стирая подсказку less
и оболочку) и восстанавливает общий режим tty по умолчанию (режим "cooked").
- оболочка ставит себя на передний план и начинает принимать ввод.
Теперь вы смотрите на пустую строку, которой предшествует уведомление о задании, когда оболочка пытается прочитать нажатия клавиш, не зная, что tty был переведен в готовый режим, и поэтому не будет отправлять какие-либо входные данные в оболочку до полная строка набрана.
Вы можете набрать здесь команду и даже отредактировать ее, если вы достаточно умны, чтобы понять, как заставить ее работать, когда ваш ввод проходит через редактор строк tty и редактор строк оболочки, причем немедленная обратная связь поступает только от редактор линии tty.
Это сложная ситуация, и для ее исправления требуется больше координации между процессами, чем позволяет ядро. Для оболочки требуется способ запроса состояния приостановки группы процессов в целом и способ различения между процессами внуков, например, less
которые обрабатывают SIGTSTP
с намерением приостановить себя вскоре после этого, и демоноподобными внуками, которые просто игнорируют SIGTSTP
с намерение продолжать работать в фоновом режиме, пока остальная часть работы приостановлена.