เชลล์ลำดับการเปลี่ยนเส้นทางสตรีมมาตรฐานหรือ 2> & 1 1> / dev / null เทียบกับ 1> / dev / null 2> & 1


3

ใครช่วยอธิบายความแตกต่างได้ไหม บางคนคิดว่าเป็นแนวปฏิบัติที่ดีที่สุดหรือไม่? ถ้าฉันจำถูกต้องฉันอย่างนั้นอ่านดังนั้นสิ่งนี้1>/dev/nullควรนำหน้านี้:2>&1

ls -al /doesNotExists 2>&1 1>/dev/null
ls -al /doesNotExists 1>/dev/null 2>&1

ls -al /doesNotExists 1>&2 2>/dev/null
ls -al /doesNotExists 2>/dev/null 1>&2

ls -la /doesNotExists 2<&1 1>/dev/null
ls -la /doesNotExists 2<&1 2>/dev/null

ls -la /doesNotExists 1<&2 1>/dev/null
ls -la /doesNotExists 1<&2 2>/dev/null

ls -la /doesNotExists 1>/dev/null 2<&1
ls -la /doesNotExists 2>/dev/null 2<&1

ls -la /doesNotExists 1>/dev/null 1<&2
ls -la /doesNotExists 2>/dev/null 1<&2

2
อ่านn>&mเป็นเปลี่ยนเส้นทางสตรีมnไปยังที่ที่mปัจจุบันเป็นผู้กำกับ ไม่เปลี่ยนเส้นทางกระแสการสตรีมn m
ctrl-alt-delor

มีความเป็นไปได้ที่ซ้ำกันของ"2> & 1" ทำอะไรในบรรทัดคำสั่ง
สกอตต์

คำตอบ:


7

ลำดับการเปลี่ยนเส้นทางสตรีมมาตรฐานของเชลล์

คำสั่งซื้อมีความสำคัญเนื่องจากผลลัพธ์แตกต่างกัน นำตัวอย่างแรกของคุณ:

ls -al /doesNotExists 2>&1 1>/dev/null

สิ่งนี้นำเฉพาะเอาต์พุตมาตรฐานไปยัง nul เนื่องจากข้อผิดพลาดมาตรฐานซ้ำกับเอาต์พุตมาตรฐานก่อนที่เอาต์พุตมาตรฐานจะถูกเปลี่ยนทิศทางไปยัง dirlist

ls -al /doesNotExists 1>/dev/null 2>&1

สิ่งนี้นำทั้งเอาต์พุตมาตรฐานและข้อผิดพลาดมาตรฐานไปยัง nul


คู่มืออ้างอิง Bash: การเปลี่ยนเส้นทาง

โปรดทราบว่าลำดับการเปลี่ยนเส้นทางมีความสำคัญ ตัวอย่างเช่นคำสั่ง

ls > dirlist 2>&1

นำทั้งเอาต์พุตมาตรฐาน (file descriptor 1) และข้อผิดพลาดมาตรฐาน (file descriptor 2) ไปยังไฟล์ dirlist ขณะที่คำสั่ง

ls 2>&1 > dirlist

นำเฉพาะเอาต์พุตมาตรฐานไปยังไฟล์ dirlist เนื่องจากข้อผิดพลาดมาตรฐานถูกทำสำเนาของเอาต์พุตมาตรฐานก่อนที่จะเปลี่ยนทิศทางเอาต์พุตมาตรฐานไปยัง dirlist

คู่มืออ้างอิงแหล่งข้อมูลBash: การเปลี่ยนเส้นทาง


เกี่ยวกับการสอน

มีแบบฝึกหัดภาพประกอบที่ดีที่บทสอนการเปลี่ยนเส้นทางภาพประกอบซึ่งทำให้เข้าใจได้ง่ายขึ้น:

ลำดับของการเปลี่ยนเส้นทางคือ "> ไฟล์ 2> & 1" เทียบกับ "2> & 1> ไฟล์"

แม้ว่าจะไม่สำคัญว่าการเปลี่ยนเส้นทางจะปรากฏที่ใดในบรรทัดคำสั่ง มีการตั้งค่าจากซ้ายไปขวา

2>&1 >file

ข้อผิดพลาดทั่วไปคือทำไฟล์คำสั่ง 2> & 1> เพื่อเปลี่ยนเส้นทางทั้ง stderr และ stdout ไปยังไฟล์ เรามาดูกันว่าเกิดอะไรขึ้น ก่อนอื่นเราพิมพ์คำสั่งในเทอร์มินัลทั่วไปของเราตัวอธิบายมีลักษณะดังนี้:

                  ---       +-----------------------+
standard input   ( 0 ) ---->| /dev/pts/5            |
                  ---       +-----------------------+

                  ---       +-----------------------+
standard output  ( 1 ) ---->| /dev/pts/5            |
                  ---       +-----------------------+

                  ---       +-----------------------+
standard error   ( 2 ) ---->| /dev/pts/5            |
                  ---       +-----------------------+

จากนั้นเชลล์ของเรา Bash จะเห็น 2> & 1 ดังนั้นจึงทำซ้ำ 1 และตัวอธิบายไฟล์มีลักษณะดังนี้:

                  ---       +-----------------------+
standard input   ( 0 ) ---->| /dev/pts/5            |
                  ---       +-----------------------+

                  ---       +-----------------------+
standard output  ( 1 ) ---->| /dev/pts/5            |
                  ---       +-----------------------+

                  ---       +-----------------------+
standard error   ( 2 ) ---->| /dev/pts/5            |
                  ---       +-----------------------+

ถูกต้องไม่มีอะไรเปลี่ยนแปลง 2 แล้วชี้ไปที่สถานที่เดียวกับ 1 ตอนนี้ Bash เห็น> ไฟล์แล้วจึงเปลี่ยน stdout:

                  ---       +-----------------------+
standard input   ( 0 ) ---->| /dev/pts/5            |
                  ---       +-----------------------+

                  ---       +-----------------------+
standard output  ( 1 ) ---->| file                  |
                  ---       +-----------------------+

                  ---       +-----------------------+
standard error   ( 2 ) ---->| /dev/pts/5            |
                  ---       +-----------------------+

และนั่นไม่ใช่สิ่งที่เราต้องการ

>file 2>&1

ทีนี้ลองดูคำสั่งที่ถูกต้อง> ไฟล์ 2> & 1 เราเริ่มจากตัวอย่างก่อนหน้านี้และไฟล์ Bash see>:

                  ---       +-----------------------+
standard input   ( 0 ) ---->| /dev/pts/5            |
                  ---       +-----------------------+

                  ---       +-----------------------+
standard output  ( 1 ) ---->| file                  |
                  ---       +-----------------------+

                  ---       +-----------------------+
standard error   ( 2 ) ---->| /dev/pts/5            |
                  ---       +-----------------------+

จากนั้นก็เห็นการซ้ำซ้อนของเรา 2> & 1:

                  ---       +-----------------------+
standard input   ( 0 ) ---->| /dev/pts/5            |
                  ---       +-----------------------+

                  ---       +-----------------------+
standard output  ( 1 ) ---->| file                  |
                  ---       +-----------------------+

                  ---       +-----------------------+
standard error   ( 2 ) ---->| file                  |
                  ---       +-----------------------+

และ voila ทั้ง 1 และ 2 จะถูกเปลี่ยนเส้นทางไปยังไฟล์


ขอบคุณกราฟิกข้อมูลที่ดี เพียงสองคำอธิบาย: 1. ls > /dev/nullมันเหมือนกับls 1> /dev/null2 เมื่อมีการ<ใช้งาน? ฉันได้พยายาม และมันไม่ได้เช่นเดียวกับls -l >file &1<2 ls >file 2>&1คือcat fileเทียบเท่ากับcat <fileมีตัวอย่างใด ๆ ที่มันไม่เทียบเท่า? ขอบคุณ
Wakan Tanka

@ WakanTanka 1 / ใช่ (1 หมายถึงเอาต์พุต std) 2 / <ใช้สำหรับเปลี่ยนเส้นทางอินพุต (ไฟล์ cat เหมือนกับไฟล์ cat <)
DavidPostill

เมื่อมีประโยชน์ในการเปลี่ยนเส้นทางอินพุตมันสามารถเปิดได้ตามที่ฉันแสดงทำไมเปลี่ยนเส้นทาง?
Wakan Tanka

เพียงเพื่อชี้แจงคำตอบในความคิดเห็น: cat <fileเป็นเช่นเดียวกับcat fileเพราะแมวอ่านจาก stdin เมื่อไม่มีข้อโต้แย้ง ls fileไม่ได้เป็นเช่นเดียวกับเป็นต่อมาคาดว่าจะพบรายชื่อของไฟล์ในแฟ้มและอดีตเพียงหนึ่งรายการไฟล์เดียวls <file file
Tiago

คำอธิบายนี้ดีมาก ขอบคุณสำหรับแผนภาพ
Jingguo Yao
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.