คำถามของคุณเกี่ยวข้องอย่างใกล้ชิดกับวิธีที่เชลล์ที่คุณใช้วิเคราะห์คำที่ผู้ใช้ป้อนในบรรทัดคำสั่ง
หากคำแรกในบรรทัดคำสั่งเป็นโปรแกรมที่อยู่ในโฟลเดอร์พิเศษ (ส่วนใหญ่กำหนดโดย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