Ctrl+D для завершения ввода строки терминала

Ctrl+D для завершения ввода строки терминала

Если я сделаю

$ cat > file.txt

текст Ctrl- DCtrl-D

Вопрос 1: Если я не нажимаю Enter, почему мне нужно нажимать Ctrl- Dдважды?

Если я сделаю

$ cat > file.txt

па бац пшшш Ctrl-Z

[2]+  Stopped         cat > file.txt
$ cat file.txt
$ cat > file.txt

па бац пшшш

Ctrl-Z

[2]+  Stopped         cat > file.txt
$ cat file.txt
pa bam pshhh

Почему во второй раз файл с 1 строкой?

решение1

В Unix большинство объектов, которые вы можете читать и записывать, — обычные файлы, каналы, терминалы, неформатированные диски — созданы так, чтобы напоминать файлы.

Программа catсчитывает данные со стандартного ввода следующим образом:

n = read(0, buffer, 512);

который запрашивает 512 байт. n— это количество фактически прочитанных байтов или -1, если произошла ошибка.

Если вы сделаете это повторно с обычным файлом, вы получите кучу 512-байтных чтений, затем несколько более короткое чтение в конце файла, затем 0, если вы попытаетесь прочитать после конца файла. Таким образом, catбудет работать до тех пор, пока nне станет <= 0.

Чтение с терминала немного отличается. После ввода строки, завершаемой нажатием клавиши Enter, readвозвращает только эту строку.

Есть несколько специальных символов, которые вы можете ввести. Один из них — Ctrl-D. Когда вы вводите его, операционная система отправляет всю текущую строку, которую вы ввели (но не себя Ctrl-D) в программу, выполняющую чтение. И вот что удивительно: если Ctrl-Dэто первый символ в строке, программе отправляется строка длиной 0 — точно так же, как программа бы увидела, если бы она только что достигла конца обычного файла.cat не нужно ничего делать по-другому, будь то чтение из обычного файла или терминала.

Еще один специальный символ — Ctrl-Z. Когда вы вводите его в любом месте строки, операционная система отменяет все, что вы вводили до этого момента, и посылает сигнал SIGTSTP программе, которая обычно останавливает (приостанавливает) ее и возвращает управление оболочке.

Итак, в вашем примере

$ cat > file.txt
pa bam pshhh<Ctrl+Z>
[2]+  Stopped         cat > file.txt

вы ввели несколько символов, которые были отброшены, а затем catостановились, не записав ничего в выходной файл.

$ cat > file.txt
pa bam pshhh
<Ctrl+Z>
[2]+  Stopped         cat > file.txt

вы ввели одну строку, которая catсчитывала и записывала данные в выходной файл, а затем Ctrl-Zостановила файл cat.

решение2

Это потому, что Ctrl+ D— это хак.

В глубине души Ctrl+ D(несмотря на то, что его называютeofхарактер) на самом деле не означает конец файла: это означает «отправить ожидающий ввод в приложение сейчас». Это на самом деле близко к значению Ctrl+ M( eol), который отправляет ожидающий ввод плюс новую строку.

Когда вы нажимаете Ctrl+ Dсразу после Ctrl+ M(т.е. в начале строки) или после другого Ctrl+ D, ожидающий ввода пуст. Таким образом, приложение получает 0 байт ввода. Вreadвызов, чтение 0 байтов сигнализирует о конце файла.


При нажатии Ctrl+ Zожидающий ввод отбрасывается. Таким образом, обрабатывается только то, что уже было отправлено в приложение (то есть cat) путем ввода новой строки или Ctrl+ Dперед нажатием Ctrl+ .Z

Связанный контент