Ctrl + D untuk mengakhiri input jalur terminal

21

Jika aku melakukan

$ cat > file.txt

teks Ctrl- DCtrl-D

Pertanyaan 1: Jika saya tidak menekan enter, mengapa saya harus menekan Ctrl- Ddua kali?

Jika aku melakukan

$ 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

Mengapa kedua kalinya file dengan 1 baris?

kabut
sumber
2
Thread ini di bawah payung situs stackexchange memiliki jawaban yang Anda lihat: stackoverflow.com/questions/7369170/… . Semoga ini bisa membantu.
Ya, meskipun tidak terkait python, pertanyaan saya adalah duplikat.
Kabut
Ketika Anda mengetik ctrl-z, apakah Anda benar-benar mendapatkan prompt shell baru, atau apakah Anda juga mendapatkan pesan tentang catdihentikan?
Mark Plotnick
Saya akan memperbarui pertanyaan
kabut

Jawaban:

30

Di Unix, sebagian besar objek yang dapat Anda baca dan tulis - file biasa, pipa, terminal, drive disk mentah - semuanya dibuat menyerupai file.

Program seperti catmembaca dari input standarnya seperti ini:

n = read(0, buffer, 512);

yang meminta 512 byte. nadalah jumlah byte yang benar-benar dibaca, atau -1 jika ada kesalahan.

Jika Anda melakukan ini berulang kali dengan file biasa, Anda akan mendapatkan banyak bacaan 512-byte, kemudian bacaan yang lebih pendek di ujung file, lalu 0 jika Anda mencoba membaca melewati akhir file. Jadi, catakan berjalan hingga n<= 0.

Membaca dari terminal sedikit berbeda. Setelah Anda mengetikkan garis, diakhiri oleh Enterkunci, readhanya mengembalikan garis itu.

Ada beberapa karakter khusus yang dapat Anda ketik. Satu adalah Ctrl-D. Saat Anda mengetik ini, sistem operasi mengirimkan semua baris saat ini yang telah Anda ketikkan (tetapi bukan Ctrl-Ddirinya sendiri) ke program yang sedang membaca. Dan inilah hal kebetulan: jika Ctrl-Dadalah karakter pertama di telepon, program akan dikirim dengan panjang 0 - seperti program akan melihat apakah hanya sampai di akhir file biasa. cat tidak perlu melakukan sesuatu yang berbeda , apakah itu membaca dari file biasa atau terminal.

Karakter spesial lainnya adalah Ctrl-Z. Saat Anda mengetiknya, di mana saja dalam satu baris, sistem operasi membuang apa pun yang Anda ketikkan sampai saat itu dan mengirimkan sinyal SIGTSTP ke program, yang biasanya berhenti (berhenti) dan mengembalikan kontrol ke shell.

Jadi, dalam contoh Anda

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

Anda mengetik beberapa karakter yang dibuang, lalu catdihentikan tanpa menulis apa pun ke file outputnya.

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

Anda mengetikkan satu baris, yang catmembaca dan menulis ke file outputnya, dan kemudian Ctrl-Zberhenti cat.

Tandai Plotnick
sumber
1
hal-hal ini hanya berlaku untuk terminal mode kanonik . Dan bahkan dalam kasus itu mereka dapat diubah.
mikeserv
@ mikeserv Itu benar. Di sini, saya ingin menjelaskan apa yang dilihat OP. Saya juga mempertimbangkan untuk menjelaskan mode terminal mentah / -icanon, karakter khusus lainnya, bagaimana mereka dapat dikustomisasi, bagaimana mereka berbeda dengan OS, dll. Tetapi tidak ingin membuat jawabannya terlalu lama.
Mark Plotnick
Apakah hal di atas menyiratkan bahwa jika input tidak melalui cat, bahwa program yang membaca data dari keyboard dan tidak berhenti saat pertama kali readmenghasilkan nol dapat terus berjalan, dan jumlah kontrol-D yang diperlukan akan ditentukan oleh jumlah nol berturut-turut yang diperlukan oleh program untuk memutuskan itu dilakukan?
supercat
@supercat Suatu program dapat terus membaca jika diinginkan. Di exeditor, jika Anda mengetikkan kontrol-D sebagai karakter pertama dari sebuah baris, editor menunjukkan kepada Anda beberapa baris program daripada keluar. (Di exdan vi, Control-D adalah mnemonik untuk "turun"). Dan dengan banyak shell, jika Anda mengetik Control-D tetapi memiliki pekerjaan yang berjalan di latar belakang, shell akan memberitahu Anda tentang hal ini daripada keluar, tetapi jika Anda mengetik Control-D lagi, shell memutuskan bahwa Anda benar-benar ingin keluar dan akan melakukannya.
Mark Plotnick
@ MarkPlotnick: Apakah ada cara dimana cegukan nol-byte ini dapat dikirim melalui pipa?
supercat
19

Itu karena Ctrl+ Dadalah hack.

Jauh di lubuk hati, Ctrl+ D(meskipun disebut eofkarakter ) sebenarnya tidak berarti end-of-file: itu berarti "mengirim input yang tertunda ke aplikasi sekarang". Ini sebenarnya dekat dengan arti Ctrl+ M( eol), yang mengirimkan input yang tertunda ditambah baris baru.

Ketika Anda menekan Ctrl+ Dsegera setelah tanda Ctrl+ M(yaitu di awal baris) atau setelah tanda Ctrl+ lainnya D, input yang tertunda kosong. Dengan demikian aplikasi menerima 0 byte input. Dalam readpanggilan, membaca 0 byte menandakan akhir file.


Saat Anda menekan Ctrl+ Z, input yang tertunda dibuang. Jadi hanya apa yang sudah dikirim ke aplikasi (yaitu cat) dengan memasukkan baris baru atau Ctrl+ Dsebelum menekan Ctrl+ Zdiproses.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
1
Informasi lebih lanjut tentang ctrl + D dari salah satu jawaban Gille dapat ditemukan di sini .
Ramesh
Seperti yang Anda katakan, Ctrl-D tidak berarti end-of-file. Sebenarnya alasan itu tidak berarti itu karena Ctrl-D adalah EOT (end-of-text).
H2ONaCl