История изменений
Исправление aureliano15, (текущая версия) :
«терминал» все-таки штука пассивная.
Отнюдь нет. Скорее наоборот.
Это именно сама программа. Конечно, далеко не только cat(1) — любая читающая ввод тем же образом. И соответственно искать это [skip] В районе read(), надо думать (хотя не уверен).
См., например, http://fliplinux.com/ctrl-d-eof.html :
Символ ^D (aka \04 или 0x4) является значением по умолчанию для специального символьного параметра eof терминала или псевдотерминального драйвера в ядре (точнее о дисциплине линии tty подключенной к устройству последовательного или псевдо-tty ). Это c_cc[VEOF] структуры termios переданной в TCSETS / TCGETS ioctl выдает на терминальное устройство проблемы, влияющие на поведение драйвера.
Типичной командой, которая отправляет эти ioctls является команда stty .
Чтобы получить все параметры:
$ stty -a скорость 38400 бод; строки 58; столбцы 191; 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 Исходный текст
Этот параметр eof имеет значение только тогда, когда терминальное устройство находится в режиме icanon .
В этом режиме драйвер терминала (а не эмулятор терминала) реализует очень простой редактор строк , где вы можете ввести Backspace для стирания символа, Ctrl-U, чтобы удалить всю строку … Когда приложение читает с терминала, он ничего не видит, пока вы не нажмете Return, в этот момент read() возвращает полную строку, включая последний символ CR или LF (по умолчанию драйвер терминала также переводит CR в LF ).
Теперь, если вы хотите отправить то, что вы набрали до сих пор, не нажимая Enter , вы можете ввести символ eof . После получения этого символа из эмулятора терминала драйвер терминала отправляет текущее содержимое строки, так что приложение, выполняющее read на нем, получит его как есть (и оно не будет содержать CR символ LF или CR ).
Теперь, если текущая строка пуста и при условии, что приложение полностью прочитает ранее введенные строки, read вернет 0 символов.
Это означает, что конец файла для приложения (когда вы читаете из файла, вы читаете, пока нечего читать). Вот почему он называется eof , потому что его отправка заставляет приложение видеть, что больше нет ввода.
Теперь современные оболочки в своем приглашении не устанавливают терминал в режиме icanon потому что они реализуют собственный редактор строк, который намного более продвинут, чем встроенный драйвер терминала. Однако в своем собственном редакторе строк , чтобы избежать путаницы пользователей, они дают символ ^D (или что бы то ни было настройку eof терминала) того же значения (чтобы обозначить eof ).
Исходная версия aureliano15, :
«терминал» все-таки штука пассивная.
Отнюдь нет. Скорее наоборот.
Это именно сама программа. Конечно, далеко не только cat(1) — любая читающая ввод тем же образом. И соответственно искать это [skip] В районе read(), надо думать (хотя не уверен).
См., например http://fliplinux.com/ctrl-d-eof.html :
Символ ^D (aka \04 или 0x4) является значением по умолчанию для специального символьного параметра eof терминала или псевдотерминального драйвера в ядре (точнее о дисциплине линии tty подключенной к устройству последовательного или псевдо-tty ). Это c_cc[VEOF] структуры termios переданной в TCSETS / TCGETS ioctl выдает на терминальное устройство проблемы, влияющие на поведение драйвера.
Типичной командой, которая отправляет эти ioctls является команда stty .
Чтобы получить все параметры:
$ stty -a скорость 38400 бод; строки 58; столбцы 191; 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 Исходный текст
Этот параметр eof имеет значение только тогда, когда терминальное устройство находится в режиме icanon .
В этом режиме драйвер терминала (а не эмулятор терминала) реализует очень простой редактор строк , где вы можете ввести Backspace для стирания символа, Ctrl-U, чтобы удалить всю строку … Когда приложение читает с терминала, он ничего не видит, пока вы не нажмете Return, в этот момент read() возвращает полную строку, включая последний символ CR или LF (по умолчанию драйвер терминала также переводит CR в LF ).
Теперь, если вы хотите отправить то, что вы набрали до сих пор, не нажимая Enter , вы можете ввести символ eof . После получения этого символа из эмулятора терминала драйвер терминала отправляет текущее содержимое строки, так что приложение, выполняющее read на нем, получит его как есть (и оно не будет содержать CR символ LF или CR ).
Теперь, если текущая строка пуста и при условии, что приложение полностью прочитает ранее введенные строки, read вернет 0 символов.
Это означает, что конец файла для приложения (когда вы читаете из файла, вы читаете, пока нечего читать). Вот почему он называется eof , потому что его отправка заставляет приложение видеть, что больше нет ввода.
Теперь современные оболочки в своем приглашении не устанавливают терминал в режиме icanon потому что они реализуют собственный редактор строк, который намного более продвинут, чем встроенный драйвер терминала. Однако в своем собственном редакторе строк , чтобы избежать путаницы пользователей, они дают символ ^D (или что бы то ни было настройку eof терминала) того же значения (чтобы обозначить eof ).