Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> การเขียนโปรแกรม Bash

เชี่ยวชาญ Linux Terminal Redirection: อ่านและเขียนข้อมูลจากที่ไหนก็ได้

บทนำ

การเปลี่ยนทิศทางของอินพุตและเอาต์พุตเป็นฟังก์ชันตามธรรมชาติของภาษาโปรแกรมหรือสคริปติ้ง ทางเทคนิค มันเกิดขึ้นโดยอัตโนมัติทุกครั้งที่คุณโต้ตอบกับคอมพิวเตอร์ อินพุตอ่านจาก 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 และเพลิดเพลินกับชีวิตที่ดี!