- TTY-абстракция
-
Стиль этой статьи неэнциклопедичен или нарушает нормы русского языка. Статью следует исправить согласно стилистическим правилам Википедии.Подсистема TTY, или TTY-абстракция — это одна из основ UNIX-систем, в частности Linux.
Содержание
История
В 1869 году был изобретён тикерный аппарат — специальный телеграфный аппарат для передачи котировок ценных бумаг. Постепенно это устройство эволюционировало в телетайп — более быстрый прибор, основанный на таблице символов ASCII. Одно время телетайпы всего мира даже были соединены в единую сеть под названием Telex, адресация в которой осуществлялась на том же принципе вращающегося вала с искателями, что и в механических автоматических телефонных станциях того времени. Сеть Telex использовалась для передачи коммерческих телеграмм. Однако в то время телетайпы пока не подключались к компьютерам.
Между тем, компьютеры того времени, хотя и были ещё довольно примитивными, уже были способны исполнять несколько задач одновременно. В частности, стало возможным взаимодействие компьютера с пользователем в режиме реального времени. Когда устаревшую пакетную модель обработки заданий заменил интерфейс командной строки, в качестве устройств ввода и вывода стали использоваться телетайпы, так как они уже были доступны на рынке.
Так как различных моделей телетайпов было множество, потребовался некий уровень программной совместимости, чтобы абстрагироваться от конкретной модели телетайпа. В UNIX и UNIX-подобных системах низкоуровневая работа с телетайпом — например, количество бит в пакете, скорость в бодах, контроль потока, контроль чётности, специальные коды для зачаточного форматирования страницы, и т. д., — возлагалась на ядро операционной системы. Такие возможности как перемещение курсора, цветной текст и т. п., стали возможны лишь в конце 1970-ых годов, с появлением видеотерминалов типа VT-100. Все эти расширенные функции оставались на попечении приложений.
С дальнейшим развитием вычислительных машин телетайпы, а затем и видеотерминалы отошли в прошлое. Однако подсистемы для работы с ними, хоть и претерпели существенные изменения, остались в ядрах операционных систем.
Сценарий использования
Предположим, пользователь набирает текст на телетайпе, и читает ответ компьютера, который тот печатает. Телетайп при этом используется как физический (реальный) терминал. Терминал этот подключается к компьютеру при помощи универсального последовательного асинхронного порта. Операционная система имеет драйвер порта, который отвечает за физическую передачу байтов по проводам (контроль чётности, контроль потока и т. п.). В простейшем случае, этот драйвер может просто передавать данные использующему его приложению. Но при этом не будет следующих функций:
Редактирование строк
Большинство пользователей допускают опечатки по время набора текста, так что клавиша забоя очень важна. Конечно, можно было бы воплотить её функциональность в самой программе, использующей телетайп. Однако в соответствии с философией UNIX, программы должны быть как можно проще. Поэтому операционная система сама предоставляет буфер для редактирования текста, а также некоторые простейшие команды редактирования — «удалить символ», «удалить слово», «удалить строку». Все эти функции реализованы внутри слоя протокола линии связи (англ.)русск. (line discipline). По умолчанию они включены; такой режим называется каноническим (canonical), или приготовленным (cooked). Программа при желании может отключить эти функции, переведя драйвер в сырой (raw) режим. (Большинство современных интерактивных программ — текстовые редакторы, почтовые агенты, оболочки, а также все программы, использующие Curses или Readline, — работают именно в этом режиме, и сами обрабатывают все команды редактирования). Упомянутый слой протокола также позволяет настраивать эхо (отображение набираемых символов на этом же самом терминале), автоматическую конвертацию признаков конца строки и возврата каретки, и т. п. Таким образом, слой протокола является примитивным разборщиком текста типа Sed, причём работающим в режиме ядра.
Смысл выделения описанной выше обработки в отдельный слой заключается в том, что дисциплину (то есть конкретный драйвер этого слоя) можно динамически менять. Например, вместо дисциплины терминала можно включить дисциплину передачи данных с пакетной коммутацией — ppp, IrDA, последовательную мышь и т. д.
Управление сеансами (англ.)русск.
Как правило, пользователь хочет запустить одновременно несколько программ, и взаимодействовать с ними по очереди. Если программа зависает, — пользователь наверняка захочет аварийно завершить (англ.)русск. её. Процессы, работающие в фоновом режиме (англ.)русск., должны блокироваться, как только они захотят вывести какой-либо текст на экран. Аналогичным образом, набираемый пользователем текст должен передаваться только активной в данный момент программе. Операционная система реализует все эти функции при помощи драйвера TTY.
Как уровень дисциплины (протокола), так и драйвер TTY являются пассивными. Иными словами, они не могут сами предпринимать каких-либо действий, а являются лишь набором процедур, которые могут быть вызваны другими процедурами. В отличие от них, сама операционная система является процессом, то есть имеет свой собственный контекст.
Система из драйвера UART-порта, дисциплины (протокола) и драйвера TTY называется устройством TTY, или просто TTY. Пользовательский процесс может изменять поведение любого TTY-устройства путём манипулирования соответствующим ему файлом (англ.)русск. в папке /dev. Естественно, для этого данный процесс должен обладать правами записи (англ.)русск. в этот файл. Поэтому когда пользователь входит в систему (англ.)русск. и подключается к определённому TTY, этот пользователь должен стать владельцем файла, соответствующего этому TTY. Именно это и делает программа login. (Сама программа login запускается от имени суперпользователя).
При этом нужно помнить, что в качестве физической линии, соединяющей терминал с компьютером, вполне может выступать и телефонная линия, что позволяет практически неограниченно удалить терминал от компьютера. С точки зрения операционной системы, единственным отличием этого случая от простого подключения терминала по UART-порту будет необходимость обрабатывать сигнал «трубка повешена», который может вдруг прийти от модема.
Теперь рассмотрим случай, когда система работает на обычном современном персональном компьютере. Дисциплина и TTY-драйвер работают так же, как и раньше, но драйвера UART-порта уже нет, так как нет телетайпа, который бы через него подключался. Вместо него используется эмулятор видеотерминала — программа, которая имитирует видеотерминал (аналог телетайпа, но с видеоэкраном вместо бумажной ленты), и отображает содержимое этого терминала на экран. При этом эта программа, в отличие от консоли, уже работает в пространстве пользователя (англ.)русск., а не ядра, что обеспечивает куда большую гибкость; например, можно выводить терминал в окне, как это делает Xterm и его многочисленные клоны.
Для того, чтобы позволить работу эмулятора терминала в пространстве пользователя, и при этом не отказываться от всей вышеописанной подсистемы TTY, был изобретён так называемый Pseudo Terminal (англ.)русск., или PTY. Псевдотерминал может быть запущен внутри другого псевдотерминала; так поступают, например, Screen или Ssh.
Место TTY в модели процессов
Как известно, процесс в ОС Linux может находиться в одном из следующих состояний:
- R (running/runnable) — процесс исполняется либо ожидает своей очереди исполняться;
- D — непрерываемый сон — процесс ожидает определённого события;
- S — прерываемый сон — процесс ожидает определённого события либо сигнала;
- T — остановка — процесс приостановлен, например, отладчиком;
- Z (zombie) — процесс уже завершился, но ещё не передал родительскому процессу свой код возврата.
При помощи команды
ps l
можно увидеть статус каждого процесса, причём в колонке WCHAN будет отображено событие, которого дожидается конкретный спящий процесс.$ ps l F UID PID PPID PRI NI VSZ RSS WCHAN STAT TTY TIME COMMAND 0 500 5942 5928 15 0 12916 1460 wait Ss pts/14 0:00 -/bin/bash 0 500 12235 5942 15 0 21004 3572 wait S+ pts/14 0:01 vim index.php 0 500 12580 12235 15 0 8080 1440 wait S+ pts/14 0:00 /bin/bash -c (ps l) >/tmp/v727757/1 2>&1 0 500 12581 12580 15 0 4412 824 - R+ pts/14 0:00 ps l
Как видно, несколько процессов совершили системный вызов wait (англ.)русск., и теперь дожидаются, когда произойдёт смена состояния одного из их дочерних процессов. Сон может быть прерываемым и непрерываемым. Прерываемый сон означает, что хотя процесс находится в очереди ожидания, он может быть запущен при получении сигнала. Все процедуры операционной системы, связанные с ожиданием того или иного события, после возвращения функции
schedule()
обязаны проверять, нет ли необработанного сигнала, и если есть — прерывать системный вызов.Колонка STAT в выводе команды ps показывает состояние процесса, но она также может содержать несколько флагов:
- s — данный процесс — ведущий процесс сессии;
- + — данный процесс входит в группу процессов, с которыми в данный момент идёт работа пользователя (то есть foreground processes — в противоположность background processes, работающим в фоновом режиме).
Именно эти атрибуты и используются для управления заданиями.
Управление заданиями и сессиями
Пусть пользователь нажал ^Z при работе с программой, или запустил программу с префиксом &, чтобы она заработала в фоновом режиме. При этом включается механизм управления заданиями.
«Задание» — это, практически, синоним «группы процессов». Пользователь может манипулировать заданиями внутри данной сессии при помощи встроенных команд оболочки, таких как
jobs
,fg
илиbg
. В свою очередь, каждая сессия управляется ведущим процессом сессии — оболочкой, которая активно общается с ядром при помощи сложного протокола, состоящего из системных вызовов и сигналов.Рассмотрим взаимоотношения процессов, заданий и сессий на примере:
Смысл в том, что каждый конвейер — это задание, потому что все процессы в конвейере должны управляться (то есть останавливаться, возобновляться или завершаться) одновременно. Именно поэтому команда
kill
позволяет посылать сигналы сразу целым группам процессов.Команда
fork
по умолчанию помещает свежесозданный процесс в ту же группу процессов, в которой находится его родитель, поэтому, например, нажатие^C
на клавиатуре повлияет и на дочерний процесс, и на родителя. С другой стороны, оболочка, являясь ведущим процессом сессии, автоматически создаёт новую группу процессов каждый раз, когда сталкивается с необходимостью запустить очередной конвейер. Задача драйвера TTY — отслеживать идентификатор активной группы процессов (который явно обновляется ведущим процессом сессии), а также размер подключённого терминала (который явно обновляется эмулятором терминала либо самим пользователем).Хотя несколько процессов могут одновременно иметь один и тот же псевдотерминал в качестве своего стандартного ввода и/или стандартного вывода, только активное (foreground) задание будет получать на вход текст, вводимый с TTY, и будет иметь право само выводить информацию на него. Если процесс, не являющийся активным, хочет вывести что-то на экран, ядро приостанавливает его при помощи сигнала.
TTY и система сигналов
Рассмотрим взаимодействие различных составляющих TTY с программами в пространстве пользователя.
Как известно, во все файлы устройств, включая файлы устройств TTY, можно читать и писать, а также настраивать их при помощи универсального системного вызова
ioctl (англ.)русск.
. Однако системный вызовioctl
должен быть вызван самим процессом, поэтому он не позволяет ядру асинхронно общаться с приложением. Для таких случаев есть система сигналов.Система сигналов — довольно грубый способ взаимодействия. Дело в том, что, хотя процессы могут перехватывать сигналы и обрабатывать их, абсолютное большинство процессов этого не делает. В результате активируется обработчик по умолчанию, который, как правило, приводит к прекращению работы программы (иногда с созданием дампа памяти). Кроме того, для обработки сигналов нет общих чётких правил, и каждый сигнал приходится рассматривать по отдельности.
Список всех сигналов доступен при помощи команды
kill -l
.Конкретно к TTY имеют непосредственное отношение следующие сигналы:
SIGHUP
Действие по умолчанию: прекратить выполнение программы
Возможные действия: прекратить выполнение программы, вызвать функцию, или ничего не делать
Драйвер UART-порта посылает сигнал SIGHUP всей сессии, когда модем переходит в состояние «трубка повешена». Обычно это убивает все процессы сессии. Некоторые программы, такие как Screen или Nohup, отделяются от своей сессии и своего TTY, поэтому их дочерние процессы не умирают при отключении модема.
SIGINT
Действие по умолчанию: прекратить выполнение программы
Возможные действия: прекратить выполнение программы, вызвать функцию, или ничего не делать
Сигнал SIGINT генерируется драйвером TTY, когда во входном потоке появляется особый символ
^C
(ASCII-код этого символа равен 3). Драйвер посылает этот сигнал активному заданию. Программа, имеющая доступ к TTY, может изменить код этого спецсимвола, либо вообще отключить генерацию этого сигнала. Менеджер сессий отслеживает настройки TTY, установленные каждой из работающих задач, и применяет их, когда эти задачи переключаются.SIGQUIT
Действие по умолчанию: выход с дампом памяти ядра
Возможные действия: выйти с дампом памяти ядра, вызвать функцию, или ничего не делать
SIGQUIT аналогичен SIGINT, но Действие по умолчанию другое, и спецсимвол другой (обычно
^\
).SIGPIPE
Действие по умолчанию: прекратить выполнение программы
Возможные действия: прекратить выполнение программы, вызвать функцию, или ничего не делать
Ядро посылает сигнал SIGPIPE процессу, который пытается писать данные в конвейер, из которого никто не читает. Этот сигнал очень полезен, потому что он позволяет конструкции типа
yes | head
нормально отработать и завершиться, а не зависнуть.SIGCHLD
Действие по умолчанию: ничего не делать
Возможные действия: вызвать функцию, или ничего не делать
Ядро посылает сигнал SIGCHLD процессу, когда один из его дочерних процессов умирает либо меняет состояние. Вместе с сигналом SIGCHLD приходит некоторая дополнительная информация, такая как идентификаторы процесса и пользователя, код возврата (или сигнал, вызвавший аварийное завершение), а также статистика использования процессорного времени. При помощи именно этого сигнала ведущий процесс сессии отслеживает выполнение своих заданий.
SIGSTOP
Действие по умолчанию: приостановить работу
Возможные действия: приостановить работу
Этот сигнал приостанавливает исполнение процесса, который его получает. Его нельзя перехватить. Как правило, ядро не использует этот сигнал. Вместо него спецсимвол
^Z
посылает сигнал SIGTSTP, который уже может быть отловлен приложением; как правило, приложение выполняет определённые действия, после чего само себя ставит на паузу — уже сигналом SIGSTOP.SIGCONT
Действие по умолчанию: пробудиться
Возможные действия: пробудиться и, при желании, вызвать функцию
Этот сигнал пробуждает усыплённый ранее процесс. Его посылает оболочка, когда пользователь вызывает команду
fg
. Так как этот сигнал нельзя отловить, неожиданный сигнал SIGCONT означает, что процесс был приостановлен, а затем пробудился.SIGTSTP
Действие по умолчанию: приостановить работу
Возможные действия: приостановить работу, вызвать функцию, или ничего не делать
SIGTSTP аналогичен SIGINT и SIGQUIT, но Действие по умолчанию другое, и спецсимвол другой (обычно
^Z
, ASCII-код 26).SIGTTIN
Действие по умолчанию: приостановить работу
Возможные действия: приостановить работу, вызвать функцию, или ничего не делать
Когда процесс, выполняющийся в фоновом режиме, пытается читать из TTY, TTY посылает этот сигнал всему заданию. Обычно это приостанавливает задание, до тех пор пока пользователь не переключится на него и не сможет ввести ожидаемые данные.
SIGTTOU
Действие по умолчанию: приостановить работу
Возможные действия: приостановить работу, вызвать функцию, или ничего не делать
Аналогичен предыдущему, но вызывается когда фоновый процесс пытается писать в TTY. Данный сигнал от данного TTY можно отключить.
SIGWINCH
Действие по умолчанию: ничего не делать
Возможные действия: вызвать функцию, или ничего не делать
Как уже упоминалось, TTY отслеживает размер терминала, однако информацию о нём нужно обновлять вручную. Для этого TTY посылает сигнал SIGWINCH активному заданию. Хорошо написанные программы, типа текстовых редакторов, адекватно реагируют на этот сигнал: узнают от TTY новый размер терминала и перерисовывают содержимое окна, чтобы оно выглядело соответствующе.
Пример
Рассмотрим следующий пример. Пусть пользователь редактирует текст в консольном текстовом редакторе. Курсор примерно посередине экрана, и редактор как раз занят выполнением задачи, требующей много процессорного времени (например, поиском и заменой слов в большом файле). В этот момент пользователь нажимает
^Z
.Так как дисциплина (протокол линии связи) была настроена на отлов этого символа, пользователю не придётся ждать, пока редактор закончит выполнение текущего задания, потому что слой дисциплины мгновенно пошлёт сигнал SIGTSTP активной задаче (то есть активной группе процессов). Причём в эту группу входит не только сам редактор, но и все его дочерние процессы.
Пусть редактор настроил ручную обработку сигнала SIGTSTP. Тогда ядро вызывает обработчик прерывания (внутри процесса текстового редактора). Этот обработчик передвигает курсор на последнюю строку на экране, путём записи определённой последовательности управляющих символов в TTY. Так как редактор является активным процессом, эти символы незамедлительно передаются и обрабатываются. Затем редактор посылает сам себе (и своей группе процессов) сигнал SIGSTOP и засыпает.
Тот факт, что текстовый редактор уснул, передаётся ведущему процессу сессии при помощи сигнала SIGCHLD (вместе с идентификаторами уснувших процессов). Когда засыпают все процессы активной задачи, ведущий процесс сессии запоминает текущие настройки TTY, и провозглашает себя активной задачей данного TTY при помощи системного вызова
ioctl
. После этого он печатает на экране уведомление для пользователя, что текущая задача была приостановлена.Если сейчас вызвать команду
ps
, она покажет, что текстовый редактор приостановлен (буква «T»). При попытке пробудить его — например, встроенной в оболочку командойbg
, или же командойkill
послав ему сигнал SIGCONT, — редактор запустит обработчик сигнала SIGCONT. Этот обработчик попытается перерисовать интерфейс путём записи последовательности управляющих символов в TTY. Однако теперь редактор — фоновый процесс, поэтому вместо отрисовки интерфейса, TTY пошлёт редактору сигнал SIGTTOU, и тот опять уснёт. Ведущий процесс сессии узнает об этом при помощи сигнала SIGCHLD, и опять выведет на экран уведомление для пользователя.Если же вместо этого вызвать команду fg, оболочка восстановит сохранённые ранее настройки TTY, вновь сделает редактор активной задачей, и пошлёт ему (и его группе процессов) сигнал SIGCONT. После этого редактор сможет нормально отрисовать свой интерфейс, и работа продолжится.
Контроль потока и блокировка ввода-вывода
Рассмотрим пример: пользователь вводит в Xterm команду
yes
. После этого в окне Xterm появляется множество буквy
. Естественно, программаyes
генерирует буквы y значительно быстрее, чем Xterm способен их принимать, обновлять свой кадровый буфер, вызывать процедуры отрисовки в X-сервере, и т. д.Чтобы сделать возможной работу в таких условиях, применяется блокировка ввода-вывода. Буфер псевдотерминала, расположенный в пространстве ядра, имеет очень ограниченный объём, и когда он забьётся буквами
y
, генерируемыми программойyes
, очередной системный вызовwrite
, осуществлённый этой программой, будет заблокирован. Программаyes
перейдёт в режим прерываемого сна, до тех пор пока Xterm не сможет хотя бы частично освободить буфер псевдотерминала.Аналогичная ситуация возникнет и в случае, если TTY подключён к последовательному порту. Если программа заполнит буфер, очередной её системный вызов
write
заблокирует процесс. При желании TTY можно открыть в неблокируемом режиме при помощи флага O_NONBLOCK; тогда вместо блокировки системный вызовwrite
вернёт ошибку EAGAIN.Однако даже если в буфере ядра ещё есть место, процесс можно заблокировать. Рассмотрим, например, такую ситуацию: к компьютеру подключён старый видеотерминал VT-100, общающийся с ним на частоте 9600 бод. Пусть компьютер только что послал терминалу сложную последовательность управляющих символов, требуя пролистать текст на экране вверх или вниз. Подобная задача сильно загружает терминал, и он становится неспособен обрабатывать поступающие данные со скоростью 9600 бод (хотя сам его UART-порт, естественно, может и дальше общаться с компьютером на этой скорости). В результате внутренний буфер терминала скоро переполнится. Поэтому на время работы терминала следует заблокировать TTY.
Для этого, как и для многих других сигналов, используются спецсимволы. Например, как уже упоминалось выше, байт
^C
не передаётся приложению, когда оно читает данные системным вызовомread
, а вместо этого вызывает сигнал SIGINT, который передаётся активному заданию. Аналогичным образом работают байты^S
(ASCII-код 19), который блокирует TTY, и^Q
(ASCII-код 17), который его пробуждает. Старые текстовые терминалы автоматически передают эти байты, основываясь на объёме оставшегося свободного места в своих буферах. Это называется программным контролем потока (в отличие от аппаратного, при котором TTY приостанавливается при помощи сигнала на специально выделенной для этого линии). Именно по этой причине Xterm блокируется, если случайно нажать^S
.Необходимо различать два случая:
- Попытка записи в TTY, заблокированный контролем потока либо переполнением буфера ядра, приведёт к блокировке данного процесса;
- Попытка записи в TTY во время работы в фоновом режиме приведёт к усыплению всей группы процессов.
Настройка TTY
Узнать TTY, который контролирует данную программную оболочку, можно при помощи утилиты
tty
.Открытый TTY можно настроить при помощи
ioctl
. Однако, данный интерфейс не является переносимым, поэтому рекомендуется использовать вместо него POSIX-совместимые обёртки (см.man 3 termios
).TTY можно также настроить прямо из консоли, используя утилиту
stty
, которая основана на упомянутом выше APItermios
:$ stty -a speed 38400 baud; rows 73; columns 238; line = 0; intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0; -parenb -parodd cs8 -hupcl -cstopb cread -clocal -crtscts -ignbrk brkint ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany imaxbel -iutf8 opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0 isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke
stty -a
выводит все настройки TTY. Конкретный TTY можно выбрать при помощи флага-F
.speed
показывает скорость UART-порта. Псевдотерминалы игнорируют это значение.rows
иcolumns
показывают размер терминала в символах. По сути, это просто две числовые переменные внутри TTY-драйвера, которые можно свободно читать и изменять. При их изменении активной задаче будет послан сигнал SIGWINCH.line
показывает номер активной дисциплины. Все имеющиеся в системе дисциплины перечислены в/proc/tty/ldiscs
.Далее перечисляются спецсимволы, а в конце — выбранные в настоящий момент опции. Тире означает, что опция отключена.
Примеры
Если открыть окно Xterm, запомнить его TTY (вызвав команду
tty
) и размер (вызвав командуstty -a
), запустить полноэкранное консольное приложение (типа vim), а потом в другом окне Xterm набратьstty -F X rows Y
, где X — имя TTY первого окна, а Y — половина его высоты, то vim в первом окне тут же получит сигнал SIGWINCH, и перерисует свой интерфейс, используя лишь половину предоставленного ему окна.
Если в окне Xterm набрать
stty intr o
, то теперь сигнал SIGINT будет генерироваться при вводе символа «o». При этом нажатие
^C
ни к чему не приведёт.Иногда в UNIX-системе не работает кнопка backspace. Это происходит потому, что эмулятор терминала посылает в TTY не тот ASCII-код, которому в этом TTY назначена функция
erase
. Чтобы решить эту проблему, нужно набратьstty erase ^H
или
stty erase ^?
. Первая команда установит символ стирания на ASCII-код 8, вторая — на 127. На приложения, работающие в сыром режиме, эти настройки не влияют.
Если в окне Xterm набрать
stty -icanon
, это отключит канонический режим. Если после этого попытаться, например, запустить программу cat, все сочетания клавиш, отвечающие за редактирование текста, такие как
^U
или даже backspace, не будут работать. Кроме того,cat
будет получать (и, соответственно, выводить) данные не строчками, как раньше, а отдельными символами.Если в окне Xterm набрать
stty -echo
, это отключит вывод на экран набираемых данных. Вызов после этого программы
cat
продемонстрирует, что набираемые на клавиатуре данные больше не выводятся на экран (то есть придётся набирать текст «вслепую»). Однако, после нажатия клавиши Enter, ядро передаст последнюю напечатанную строчку программеcat
, и она уже выведет её на экран.Если в окне Xterm набрать
stty -tostop
, это позволит процессам, работающим в фоновом режиме, выводить данные на экран, вместо того чтобы быть заблокированными. Например, команда
(sleep 5; echo hello, world) &
покажет приглашение оболочки, однако через 5 секунд в консоль будет выведена строчка
«hello, world»
. Если в это время работать с терминалом (например, набирать какой-то текст), то эта строчка вклинится прямо в этот набираемый текст. Если же набратьstty tostop
, то запуск команды
(sleep 5; echo hello, world) &
приведёт к блокировке этого процесса сигналом SIGTTOU, потому что через 5 секунд он попытается вывести на экран текст, находясь при этом в фоновом режиме. Обычно оболочка в таких случаях выводит на экран предупреждающую надпись (либо сразу же, либо при выводе очередного приглашения). Команда
stty sane
возвращает настройки TTY к «вменяемым» параметрам.
Больше информации можно найти в системе
info (англ.)русск.
(info libc, «Job Control»).Ссылки
Категории:- POSIX
- UNIX
Wikimedia Foundation. 2010.