Ctrl + D для закінчення введення термінальної лінії


21

Якщо я це роблю

$ cat > file.txt

текст Ctrl- DCtrl-D

Запитання 1: Якщо я не натискаю клавішу Enter, навіщо мені натискати Ctrl- Dдвічі?

Якщо я це роблю

$ cat > file.txt

pa bam pshhh Ctrl-Z

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

pa bam pshhh

Ctrl-Z

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

Чому вдруге файл із 1 рядком?


2
Ця нитка під парасолькою сайтів stackexchange має відповідь, яку ви дивитесь: stackoverflow.com/questions/7369170/… . Сподіваюся, це допомагає.

Так, навіть якщо це не стосується пітона, моє питання - це дублікат.
туман

Коли ви вводите ctrl-z, чи справді ви отримуєте лише нове запит оболонки, або ви також отримуєте повідомлення про catзупинку?
Марк Плотнік

Я оновлю питання
туман

Відповіді:


30

У 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.


1
ці речі стосуються лише терміналів канонічного режиму . І навіть у такому випадку їх можна змінити.
mikeserv

@mikeserv Це правда. Тут я хотів пояснити лише те, що бачив ОП. Я також розглядав опис режиму терміналу raw / -icanon, інші спеціальні символи, як їх можна налаштувати, як вони відрізняються від ОС тощо, але не хотів робити відповідь занадто довго.
Марк Плотнік

Чи означає сказане вище, що якщо введення не проходило cat, програма, яка читала дані з клавіатури і не зупинялася з першого разу, readдала нуль, може продовжувати роботу, а кількість необхідних контрольних D визначається за кількість послідовних нулів, необхідних для вирішення програми?
supercat

@supercat Програма може продовжувати читати, якщо хоче. У exредакторі, якщо ви вводите control-D як перший символ рядка, редактор показує вам кілька рядків програми, а не вихід. (В exі vi, Control-D - мнемонічне значення для "вниз"). І з багатьма оболонками, якщо ви введете Control-D, але у вас є завдання, що працюють у фоновому режимі, оболонка інформує вас про це, а не про вихід, але якщо ви знову введете Control-D, оболонка вирішить, що ви дійсно хочете вийти з нього все одно і зробить це.
Марк Плотнік

@MarkPlotnick: Чи є якийсь спосіб, через який ці нульові байтові гикавки можуть бути надіслані через трубу?
supercat

19

Це тому, що Ctrl+ D- це хак.

Глибоко вниз, Ctrl+ D(незважаючи на те, що його називають eofсимволом ), насправді не означає закінчення файлу: це означає "надіслати очікуваний вхід до програми зараз". Це насправді близьке до значення Ctrl+ M( eol), яке надсилає очікуваний вхід плюс новий рядок.

Коли ви натискаєте Ctrl+ Dвідразу після Ctrl+ M(тобто на початку рядка) або після іншого Ctrl+ D, очікуваний вхід порожній. Таким чином, програма отримує 0 байт введення. Під час readдзвінка читання 0 байт сигналізує про закінчення файлу.


Коли ви натискаєте Ctrl+ Z, очікуваний вхід відкидається. Таким чином, обробляється лише те, що вже було надіслано до програми ( catвводячи нову лінію або Ctrl+ Dперед натисканням Ctrl+ Z).


1
Більше інформації про ctrl + D з однієї з відповідей Гілле можна знайти тут .
Рамеш

Як ви вже говорили, Ctrl-D не означає закінчення файлу. Насправді причина це не означає, що це тому, що Ctrl-D є EOT (в кінці тексту).
H2ONaCl
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.