บทนำ
การเปลี่ยนทิศทางของอินพุตและเอาต์พุตเป็นฟังก์ชันตามธรรมชาติของภาษาโปรแกรมหรือสคริปติ้ง ทางเทคนิค มันเกิดขึ้นโดยอัตโนมัติทุกครั้งที่คุณโต้ตอบกับคอมพิวเตอร์ อินพุตอ่านจาก stdin (standard input ปกติคือคีย์บอร์ดหรือเมาส์) เอาต์พุตไป stdout (standard output สตรีมข้อความหรือข้อมูล) และข้อผิดพลาดไป stderr การเข้าใจว่าสตรีมข้อมูลเหล่านี้มีอยู่ช่วยให้คุณควบคุมได้ว่าข้อมูลไปไหนเมื่อคุณใช้ shell เช่น Bash หรือ Zsh
Standard in, standard out, และ standard error มีอยู่เป็น filesystem locations บน Linux คุณเห็นพวกมันใน /dev:
$ ls /dev/std* /dev/stderr@ /dev/stdin@ /dev/stdout@
คุณไม่ค่อยทำอะไรกับพวกมันโดยตรง แต่มันมีประโยชน์บางครั้งที่จะคิดถึงพวกมันเป็น meta-locations ที่คุณส่งข้อมูลได้
พื้นฐานของ redirection เรียบง่าย: ใช้ตัวอักษร > บางจำนวนเพื่อเปลี่ยนทิศทางเอาต์พุต และ < บางจำนวนเพื่อเปลี่ยนทิศทางอินพุต
การเปลี่ยนทิศทางเอาต์พุต (Redirecting output)
เพื่อเขียน output ของคำสั่ง ls ไปไฟล์:
$ ls > list.txt
คุณไม่เห็น output ของ ls ตามปกติ เพราะ output ถูกเขียนไปที่ไฟล์ list.txt แทนหน้าจอ มัน versatile มากจนคุณสามารถใช้ copy เนื้อหาไฟล์หนึ่งไปอีกไฟล์ได้ มันไม่จำเป็นต้องเป็น text file คุณสามารถใช้ redirection สำหรับ binary data:
$ cat image.png > picture.png
(หากคุณสงสัยว่าทำไมต้องทำอย่างนั้น มันเป็น repercussion ที่มีประโยชน์บางครั้งบน file permissions)
การเปลี่ยนทิศทางอินพุต (Redirecting input)
คุณสามารถ redirect input "เข้า" คำสั่งได้เช่นกัน นี้ arguably less useful กว่า redirecting output เพราะคำสั่งหลายตัว hard-coded ไว้แล้วว่ารับ input จาก argument ที่คุณให้ มันอาจมีประโยชน์ อย่างไรก็ตาม เมื่อคำสั่งคาดหวังรายการ arguments และคุณมี arguments เหล่านั้นในไฟล์ และอยาก "copy และ paste" พวกมันจากไฟล์เข้าสู่เทอร์มินัลอย่างรวดเร็ว (แต่คุณไม่ได้อยาก copy-paste จริงๆ):
$ sudo dnf install $(<package.list)
Common uses ของ input redirection คือ here-document (หรือแค่ here-doc สำหรับ short) และเทคนิค here-string วิธีอินพุตนี้ redirect บล็อกข้อความเข้าสู่ standard input stream จนถึง end-of-file marker พิเศษ (ส่วนใหญ่ใช้ EOF แต่มันอาจเป็น string ใดๆ ที่คุณคาดว่าจะ unique) ลองพิมพ์นี้ (จนถึง instance ที่สองของ EOF) ลงในเทอร์มินัล:
$ echo << EOF > foo > bar > baz > EOF
ผลลัพธ์ที่คาดหวัง:
foo bar baz
here-doc เป็น trick ทั่วไปที่ Bash scripters ใช้ dump หลายบรรทัดของข้อความลงไฟล์หรือหน้าจอ ตราบใดที่คุณไม่ลืมจบ clause ด้วย end-of-file marker มันเป็นวิธีมีประสิทธิภาพหลีกเลี่ยงรายการ echo หรือ printf ที่ unwieldy
here-string คล้าย here-doc แตประกอบด้วยแค่หนึ่ง string (หรือหลาย strings แต่งเป็น single string ด้วย quotation marks):
$ cat <<< "foo bar baz" foo bar baz
การเปลี่ยนทิศทางข้อความข้อผิดพลาด
ข้อความข้อผิดพลาดไปที่สตรีมชื่อ stderr ถูกกำหนดเป็น 2> สำหรับการเปลี่ยนทิศทาง คำสั่งนี้ส่งข้อความข้อผิดพลาดไปไฟล์ output.log:
$ ls /nope 2> output.log
การส่งข้อมูลไป /dev/null
เหมือนกับที่มี locations สำหรับ standard in, standard out, และ error มี location สำหรับ nowhere บน Linux filesystem มันชื่อ null และอยู่ใน /dev ดังนั้นมักอ่านว่า "devnull" โดยคนที่ใช้บ่อยจนไม่ว่าจะพูด "slash dev slash null"
คุณสามารถส่งข้อมูลไป /dev/null ด้วย redirection ตัวอย่าง คำสั่ง find มัก verbose และมักรายงาน permission conflicts ขณะค้นหาผ่านไฟล์ของคุณ:
$ find ~ -type f /home/seth/actual.file find: `/home/seth/foggy': Permission denied find: `/home/seth/groggy': Permission denied find: `/home/seth/soggy': Permission denied /home/seth/zzz.file
คำสั่ง find ประมวลผลนั้นเป็น error ดังนั้นคุณสามารถ redirect แค่ error messages ไป /dev/null:
$ find ~ -type f 2> /dev/null /home/seth/actual.file /home/seth/zzz.file
การใช้งาน Redirection
Redirection เป็นวิธีมีประสิทธิภาพในการย้ายข้อมูลจากที่หนึ่งไปอีกที่ใน Bash คุณอาจไม่ใช้ redirection ตลอดเวลา แตการเรียนรู้ใช้มันเมื่อต้องการสามารถประหยัดเวลามากที่เปิดไฟล์และ copy-paste ข้อมูลโดยไม่จำเป็น ซึ่งโดยทั่วไปต้องการ mouse movement และ key presses เยอะ อย่าลجำเป็นไปถึงขั้นสุด ลองใช้ redirection และเพลิดเพลินกับชีวิตที่ดี!