คำถามของคุณเกี่ยวข้องอย่างใกล้ชิดกับวิธีที่เชลล์ที่คุณใช้วิเคราะห์คำที่ผู้ใช้ป้อนในบรรทัดคำสั่ง
หากคำแรกในบรรทัดคำสั่งเป็นโปรแกรมที่อยู่ในโฟลเดอร์พิเศษ (ส่วนใหญ่กำหนดโดยPATH
) และไม่มีการให้อักขระพิเศษอีก (ขึ้นอยู่กับเชลล์ที่คุณใช้) คำที่ตามมาทั้งหมดจะถูกส่งผ่านโดยคั่นด้วยช่องว่างหรือแท็บ โปรแกรมในรูปแบบพิเศษเช่นอาร์เรย์ ด้วยแต่ละคำเป็นองค์ประกอบหนึ่งในอาร์เรย์
วิธีที่โปรแกรมคุณจะเรียกใช้การตีความอาร์กิวเมนต์ (อยู่ในอาร์เรย์) จะขึ้นอยู่กับว่าโปรแกรมถูกตั้งค่าอย่างไร มีมาตรฐานเสมือนว่าไวยากรณ์ของข้อโต้แย้งควรมีลักษณะอย่างไร แต่โดยทั่วไปโปรแกรมเมอร์นั้นว่างทั้งหมด ดังนั้นอาร์กิวเมนต์แรกสามารถตีความได้ว่าเป็นชื่อของไฟล์หรือสิ่งที่โปรแกรมเมอร์คิดในเวลาที่เขาเขียนโปรแกรม
ในกรณีที่คุณเพิ่มอักขระพิเศษ<
หรือ>
ในบรรทัดคำสั่งของคุณเชลล์จะไม่ผนวก<
และ>
ไม่ใช้คำที่ตามมาในอาร์เรย์ที่จะถูกส่งผ่านไปยังโปรแกรม ด้วย<
หรือ>
ให้เปลือกเริ่มทำสิ่งแฟนซีสนับสนุนโดยเคอร์เนลพื้นฐาน ( ท่อคำหลัก) เพื่อให้เข้าใจว่าเกิดอะไรขึ้นคุณต้องเข้าใจว่าอะไรSTDIN
และSTDOUT
(เนื่องจากไม่เกี่ยวข้องทันทีที่ฉันละเว้นSTDERR
) คืออะไร
ทุกอย่างที่คุณเห็นในเทอร์มินัลของคุณ (ในกรณีส่วนใหญ่ของจอแสดงผลของคุณ) เขียนโดยเชลล์หรือโปรแกรมอื่น ๆ ที่คุณเรียกใช้ก่อนหน้านี้ไปยังไฟล์พิเศษ (ในยูนิกซ์ทุกอย่างเป็นไฟล์ ) STDOUT
ไฟล์นี้มีรหัสพิเศษและถูกเรียกว่า หากโปรแกรมต้องการที่จะอ่านข้อมูลจากแป้นพิมพ์มัน dosn't สำรวจแป้นพิมพ์โดยตรง (อย่างน้อยในกรณีส่วนใหญ่) STDIN
แต่อ่านจากแฟ้มพิเศษที่เรียกว่า ภายในไฟล์นี้เชื่อมต่อกับอุปกรณ์อินพุตมาตรฐานแป้นพิมพ์ของคุณในกรณีส่วนใหญ่
หากเชลล์อ่าน<
หรือ>
ในบรรทัดคำสั่งที่แยกวิเคราะห์มันจะจัดการSTDIN
หรือSTDOUT
ในชนิดเฉพาะสำหรับเวลาที่โปรแกรมที่เกี่ยวข้องกำลังทำงานอยู่ STDIN
และไม่ได้STDOUT
ชี้ไปที่เทอร์มินัลหรืออุปกรณ์อินพุตมาตรฐานอีกต่อไป แต่จะไปที่ชื่อไฟล์ที่ตามมาในบรรทัดคำสั่ง
ในกรณีของสองบรรทัด
cat file_name
cat < file_name
พฤติกรรมที่สังเกตได้นั้นเหมือนกันเพราะผู้พัฒนาที่เกี่ยวข้องนั้นทำการcat
อ่านข้อมูลจากSTDIN
หรืออ่านข้อมูลจากไฟล์ซึ่งมีชื่อที่ได้รับเป็นอาร์กิวเมนต์บรรทัดคำสั่งแรก (ซึ่งเป็นองค์ประกอบแรกในอาร์เรย์ที่เชลล์ส่งไปcat
) ต่อมาcat
เขียนเนื้อหาทั้งหมดของfile_name
หรือไปยังสถานีเนื่องจากเราไม่ได้สั่งให้เปลือกในการจัดการSTDIN
STDOUT
จำไว้ว่าในบรรทัดที่สองเชลล์ของคุณใช้STDIN
วิธีนี้มันไม่ได้ชี้ไปที่อุปกรณ์อินพุตมาตรฐานของคุณอีกต่อไป แต่ชี้ไปที่ไฟล์ที่เรียกว่าfile_name
ในไดเรกทอรีการทำงานปัจจุบันของคุณ
ในกรณีอื่น ๆ ของสาย
man < file_name
man
ไม่ได้หมายถึงการอ่านอะไรจากSTDIN
ถ้ามันถูกเรียกโดยไม่มีข้อโต้แย้งเช่นอาร์เรย์ที่ว่างเปล่า ดังนั้นสาย
man < file_name
เท่ากับ
man
ยกตัวอย่างเช่นman
จะอ่านอะไรบางอย่างจากSTDIN
, เกินไปถ้าคุณผ่านไป-l -
man
ด้วยตัวเลือกนี้ที่ให้ไว้ในบรรทัดคำสั่งคุณสามารถแสดงเนื้อหาของสิ่งที่man
อ่านจากSTDIN
ใน terminal ของคุณ ดังนั้น
man -l - < file_name
จะทำงานได้ด้วย (แต่โปรดระวังman
ไม่ใช่เพียงเพจเจอร์ แต่ยังแยกวิเคราะห์อินพุตของไฟล์และดังนั้นเนื้อหาไฟล์และเนื้อหาที่แสดงอาจแตกต่างกัน)
ดังนั้นวิธีการSTDIN
, STDOUT
และการขัดแย้งบรรทัดคำสั่งจะถูกตีความขึ้นทั้งหมดให้กับนักพัฒนาที่สอดคล้องกัน
ฉันหวังว่าคำตอบของฉันจะทำให้สิ่งต่าง ๆ ชัดเจนขึ้น
man -l - < file_name
การman
ตีความSTDIN
เป็นอาร์กิวเมนต์ แต่มันล้มเหลวในระบบของฉันด้วยSTDERR
:man -l - < tee man: invalid option -- l man, version 1.6c