ทำไม Ctrl-D (EOF) ออกจากเชลล์?


68

คุณกำลัง "จบไฟล์" โดยการใส่ลำดับการหลบหนีนี้หรือไม่นั่นคือเซสชันเชลล์เชิงโต้ตอบถูกมองว่าเป็นสตรีมไฟล์จริงโดยเชลล์เช่นเดียวกับสตรีมไฟล์อื่น ๆ ถ้าเป็นเช่นนั้นไฟล์ไหน?

หรือCtrl+ Dสัญญาณเป็นเพียงตัวยึดตำแหน่งซึ่งหมายความว่า "ผู้ใช้ป้อนข้อมูลเสร็จแล้วและคุณอาจยุติ"



6
FYI ในทุบตีคุณสามารถทำได้set -o ignoreeofเพื่อเปลี่ยนพฤติกรรมที่
Keith

ฉันมีปัญหาเดียวกัน. ข้อผิดพลาดของฉันคือฉันตั้งใจกำหนดทางลัดโปรไฟล์ konsole ให้กับ "Ctrl + d" โดยไม่ตั้งใจ ไม่ใช่ช่วงเวลาที่ภูมิใจที่สุดของฉัน
Brian Simonsen

คำตอบ:


78

^Dตัวอักษร (ยังเป็นที่รู้จัก\04หรือ 0x4, END ของการส่งผ่านใน Unicode) เป็นค่าเริ่มต้นสำหรับeofพิเศษพารามิเตอร์ตัวอักษรการควบคุมของสถานีหรือโปรแกรมควบคุมหลอกขั้วใน kernel (อย่างแม่นยำมากขึ้นของttyวินัยบรรทัดแนบมากับอนุกรมหรือหลอก อุปกรณ์ tty ) นั่นเป็นc_cc[VEOF]ของtermiosโครงสร้างส่งผ่านไปยัง TCSETS / การ TCGETS ioctlหนึ่งประเด็นที่อุปกรณ์ปลายทางที่จะส่งผลกระทบต่อพฤติกรรมของคนขับรถ

คำสั่งทั่วไปที่ส่งคำสั่งเหล่านั้นioctlsคือsttyคำสั่ง

เพื่อดึงพารามิเตอร์ทั้งหมด:

$ stty -a
ความเร็ว 38400 baud; แถว 58; คอลัมน์ 191; บรรทัด = 0;
intr = ^ C; เลิก = ^ \; ลบ = ^ ?; kill = ^ U; eof = ^ D ; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^ Q; stop = ^ S; susp = ^ Z; rprnt = ^ R; werase = ^ W; lnext = ^ V; flush = ^ O;
ต่ำสุด = 1; เวลา = 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

ว่าeofพารามิเตอร์ที่เกี่ยวข้องเฉพาะเมื่ออุปกรณ์ปลายทางอยู่ในicanonโหมด

ในโหมดนั้นไดรเวอร์เทอร์มินัล (ไม่ใช่เทอร์มินัลอีมูเลเตอร์) ใช้เครื่องมือแก้ไขบรรทัดอย่างง่ายซึ่งคุณสามารถพิมพ์Backspaceเพื่อลบอักขระCtrl-Uเพื่อลบทั้งบรรทัด ... เมื่อแอปพลิเคชันอ่านจากอุปกรณ์เทอร์มินัล คุณกดReturnที่จุดที่read()ส่งกลับบรรทัดเต็มรวมถึงLFอักขระตัวสุดท้าย(โดยค่าเริ่มต้นไดรเวอร์เทอร์มินัลยังแปลCRส่งโดยเทอร์มินัลของคุณReturnไปยังLF)

ทีนี้ถ้าคุณต้องการส่งสิ่งที่คุณพิมพ์โดยไม่ต้องกดปุ่มEnterนั่นคือสิ่งที่คุณสามารถป้อนeofตัวละคร เมื่อได้รับตัวอักษรนั้นจากเทอร์มินัลอีมูเลเตอร์แล้วไดรเวอร์ของเทอร์มินัลจะส่งเนื้อหาปัจจุบันของบรรทัดเพื่อให้แอปพลิเคชันที่ทำงานอยู่ด้านreadบนจะได้รับตามที่เป็นอยู่ (และจะไม่มีLFอักขระต่อท้าย)

ตอนนี้ถ้าบรรทัดปัจจุบันว่างเปล่าและหากแอปพลิเคชันได้อ่านบรรทัดที่ป้อนก่อนหน้าอย่างสมบูรณ์แล้วreadจะส่งคืนอักขระ 0 ตัว

นั่นหมายถึงการสิ้นสุดไฟล์ไปยังแอปพลิเคชัน (เมื่อคุณอ่านจากไฟล์คุณจะอ่านจนกว่าจะไม่มีอะไรให้อ่านอีกต่อไป) นั่นเป็นสาเหตุที่เรียกว่าeofตัวละครเพราะการส่งมันทำให้แอปพลิเคชั่นเห็นว่าไม่มีการป้อนข้อมูลเพิ่มเติม

ตอนนี้เชลล์ทันสมัยที่พรอมต์ของพวกเขาไม่ได้ตั้งค่าเทอร์มินัลในicanonโหมดเพราะพวกเขาใช้เครื่องมือแก้ไขบรรทัดของตัวเองซึ่งมีความก้าวหน้ามากกว่าตัวขับเทอร์มินัลในตัว อย่างไรก็ตามในตัวแก้ไขบรรทัดของตนเองเพื่อหลีกเลี่ยงความสับสนของผู้ใช้พวกเขาให้^Dตัวละคร (หรือสิ่งที่การeofตั้งค่าของเทอร์มินัลกับบางคน) ความหมายเดียวกัน (เพื่อบ่งบอกeof)


ฉันรู้เมื่อฉันเริ่มอ่านความคิดเห็นนี้ว่ามันถูกเขียนโดยสเตฟาน :) คุณสเตฟานเป็นฮีโร่ของฉันทุบตีและฉันไม่ได้เหน็บแนม ฉันชอบทานอาหารกลางวันกับคุณและเลือกสมองของคุณถ้าคุณเคยอยู่ในนิวยอร์คฉันกำลังซื้อ
Gregg Leventhal

@GreggLeventhal ขอบคุณ โอกาสที่ฉันจะไปนิวยอร์คทุกเวลาเร็ว ๆ นี้จะค่อนข้างบาง
Stéphane Chazelas

เป็น EOT แม้ใน ASCII 7 บิต
Bananguin

9

CTRL_D เป็นเพียงสัญญาณบอกว่านี่คือจุดสิ้นสุดของสตรีมข้อความ คุณไม่ได้จบไฟล์ด้วยคุณสิ้นสุดสตรีมอินพุตของคุณโดยพิมพ์ นอกจากนี้ CTRL_D ไม่รองรับอักขระหรือไบต์ใด ๆ ตามที่คุณสามารถค้นหาด้วย hexdump เครื่องมือ

# cat >test.txt
asdf# hexdump -C test.txt 
00000000  61 73 64 66                                       |asdf|
00000004
# ll test.txt 
-rw-r--r-- 1 root root 4 Jan 21 11:55 test.txt

5
และเหตุผลที่มันจบเปลือกคือเปลือกนั้นเป็นกระบวนการที่รับอินพุตและทำกับมัน เมื่อคุณบอกว่าจะไม่มีการป้อนข้อมูลเพิ่มเติมที่กำลังจะมาไม่มีอะไรที่เชลล์จะต้องทำอีกต่อไป
เจนนี่ D

ฉันตระหนักว่าลำดับ EOF ไม่มีอยู่โดยพูดไฟล์ข้อความและสร้างขึ้นโดยระบบปฏิบัติการเพื่อรายงานว่าไม่มีข้อมูลให้อ่านอีกต่อไป ฉันคิดว่าสิ่งที่ฉันถามจริง ๆ คือถ้าเซสชันเทอร์มินัลโต้ตอบถูกมองว่าเป็นสตรีมไฟล์จริงโดยเชลล์เช่นเดียวกับสตรีมไฟล์อื่น ๆ
Geeb

เพิ่งแก้ไขคำถามเดิมเพื่อชี้แจง
Geeb

2
ใช่กระแสที่ไปสู่การทุบตีคือกระแสข้อมูลที่เข้าเหมือนกัน CTRL_D ส่งสัญญาณว่าอินพุตสตรีมอยู่ที่ท้ายสุดและ bash สามารถออกได้
Thorsten Staerk
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.