(และทำไม) ใช้ stderr สำหรับทั้งการอ่านและการเขียนได้อย่างไร


12

ตามคำตอบนี้โดย schily , lessอ่านคำสั่งนำทางจาก stderr /dev/ttyถ้ามันไม่สามารถที่จะเปิด

ดูเหมือนว่าจะทำให้งงงวยเนื่องจากฉันไม่เคยเห็นสิ่งใดที่เขียนไปยังสตรีม stderr ของโปรแกรมอื่นและฉันไม่รู้ว่าฉันจะทำอย่างไรให้สำเร็จ

จุดประสงค์ของ stderr ที่เปิดสำหรับการอ่านและการเขียนคืออะไร? และถ้ามันมีประโยชน์ฉันจะใช้มันกับระบบที่ทันสมัยได้อย่างไร? (มีไวยากรณ์อาร์เคนบางอย่างเพื่อไพพ์บางสิ่งลงใน stderr แทนที่จะเป็น stdin หรือไม่?)

คำตอบ:


7

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

ก่อนการเปลี่ยนเส้นทาง stdin, stdout และ stderr นั้นเป็นไปตามที่คาดว่าจะเชื่อมต่อกับอุปกรณ์เดียวกัน

#ctrl-alt-delor:~$
#↳ ll /dev/std*
lrwxrwxrwx 1 root root 15 Jun  3 20:58 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root 15 Jun  3 20:58 /dev/stdin -> /proc/self/fd/0
lrwxrwxrwx 1 root root 15 Jun  3 20:58 /dev/stdout -> /proc/self/fd/1

#ctrl-alt-delor:~$
#↳ ll /proc/self/fd/*
lrwx------ 1 richard richard 64 Jun 30 19:14 /proc/self/fd/0 -> /dev/pts/12
lrwx------ 1 richard richard 64 Jun 30 19:14 /proc/self/fd/1 -> /dev/pts/12
lrwx------ 1 richard richard 64 Jun 30 19:14 /proc/self/fd/2 -> /dev/pts/12

ดังนั้นหลังจากทิศทางใหม่ส่วนใหญ่ (นั่นคือถ้า stderr) ไม่ได้เปลี่ยนเส้นทาง stderr ยังคงเชื่อมต่อกับขั้ว ดังนั้นจึงสามารถอ่านได้เพื่อรับคีย์บอร์ด

สิ่งเดียวที่จะหยุดไฟล์ที่ใช้ในทิศทางที่ไม่คาดคิดคือการประชุมและไปป์นั้นเป็นทิศทางเดียว

ตัวอย่างอื่นลอง:

cat | less

ข้อผิดพลาดนี้เกิดขึ้นหลังจากหน้าเว็บเมื่อlessพยายามอ่านเครื่องเทอร์มินัล (นี่ไม่ใช่เรื่องที่น่าประหลาดใจเช่นเดียวกับcatการอ่านเครื่องอ่าน)

/dev/ttyมันลึกลับมากกว่านั้นไม่ใช่ลิงก์เข้า/proc/selfมา

#ctrl-alt-delor:~$
#↳ ll /dev/tty
crw-rw-rw- 1 root tty 5, 0 Jun 29 09:18 /dev/tty

ดูว่าความสัมพันธ์ระหว่างเทอร์มินัลการควบคุมปัจจุบันของฉันกับ `/ dev / tty` คืออะไร? สำหรับคำอธิบาย ขอบคุณ @StephenKitt สำหรับลิงก์


เกี่ยวกับ/dev/ttyดูคำถามนี้
Stephen Kitt

6

เมื่อคุณเข้าสู่ระบบ stdin, stdout และ stderr เชื่อมต่อกับเทอร์มินัลที่คุณเข้าสู่ระบบเพื่อให้แน่นอนยิ่งขึ้น tty จะเปิดขึ้นโดยทั่วไปและ stdout และ stderr เป็นผลมาจากสองdup(2)การดำเนินงานในไฟล์อธิบายแรก สิ่งนี้ยอมให้อ่านจาก stderr เพื่อรับอินพุตจาก termnal

ดังที่กล่าวไว้ในคำตอบอื่น ๆ โปรแกรมอ่านจาก stderr เพื่อรับการตอบกลับแบบโต้ตอบกับคำถาม

เนื่องจากผู้ใช้ไม่สามารถรู้ได้ว่าสถานการณ์ใดที่โปรแกรมอ่านจาก stderr จึงเป็นความพยายามที่ไร้ประโยชน์ในการเขียนข้อมูลลงใน stderr จากโปรแกรมอื่น

โปรดทราบว่าโปรแกรมวันนี้มักจะพยายามเปิด/dev/ttyและใช้ stderr ในกรณีที่ใช้งานไม่ได้เท่านั้น

โปรแกรมที่อ่านจาก stderr มักจะไม่เคยมีการแก้ไขตั้งแต่ก่อนปี 1979 และโปรแกรมดังกล่าวปกติมีโครงสร้างเช่น:

int i 1;

หรือ

i =* 2;

ที่ไม่ได้รับการยอมรับจากคอมไพเลอร์ C ที่ทันสมัย ดังนั้นจึงไม่น่าเป็นไปได้ที่คุณในวันนี้จะพบโปรแกรมที่ไม่เคยเปิด/dev/ttyแต่อ่านการตอบกลับแบบโต้ตอบจาก stderr


ดังนั้นหากฉันเข้าใจถูกต้องเชลล์stderrจะเชื่อมต่อกับ tty เมื่อstdinเปลี่ยนเส้นทาง (ผ่านไพพ์หรือวิธีการอื่น) หรือเพียงแค่เชื่อมต่อstderrกับ tty เสมอ?
Draconis

1
เมื่อคุณเข้าสู่ระบบ stderr เชื่อมต่อกับสถานีเข้าสู่ระบบของคุณ
Schily

2
i =+ 1เป็นที่ถูกต้องสมบูรณ์ C i = (+1)และมีค่าเท่ากับ ได้รับ, อดีตเป็นผู้สมัครที่ดีสำหรับการประกวด C underhanded
G. Sliepen

1
ตกลงอาจเป็นได้ว่าเพิ่งสร้างคำเตือน ฉันเปลี่ยนรหัสเป็นอย่างอื่นจาก C ในปี 1977
306 schily schily

1
มันดูเหมือนว่าฉันรู้ของเปลือกหอยมากขึ้นเนื่องจากผมไม่ทราบว่าของอย่างน้อยหนึ่งเชลล์ที่อ่านจากอื่น ๆ นอกเหนือจากการป้อนข้อมูลมาตรฐาน (-:
JdeBP
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.