หากคุณเคยใช้ไพพ์และการเปลี่ยนเส้นทางภายใต้เชลล์ Linux ของคุณ บางครั้งคุณอาจต้องใช้ประโยชน์จาก tee
อรรถประโยชน์
ตี๋ทำอะไร?
คำสั่งเช่น
ls
จะแสดงเนื้อหาของไดเร็กทอรีปัจจุบันของคุณ กล่าวคือ จะแสดงเนื้อหาเหล่านี้เป็น stdout (เอาต์พุตมาตรฐาน) ซึ่งปกติคือหน้าจอของคุณ หรือเพื่อให้แม่นยำยิ่งขึ้นคือจอแสดงผลเทอร์มินัลเสมือนของคุณ
คำสั่งเช่น
ls > file123
จะไม่แสดงสิ่งใดบนหน้าจอของคุณ นั่นเป็นเพราะว่า >
sign เปลี่ยนเส้นทางเอาต์พุตทั้งหมดไปยังไฟล์แทนที่จะแสดงไปที่ stdout file123 จะเต็มไปด้วยเนื้อหาที่เคยแสดงบนหน้าจอของคุณก่อนหน้านี้
ในการแสดงเนื้อหาของไดเร็กทอรีของคุณบนหน้าจอและเขียนสิ่งนี้ลงในไฟล์ คุณใช้คำสั่งสองคำสั่ง กับ tee
คุณสามารถทำทั้งสองสิ่งนี้พร้อมกันได้
ls | tee file123
เหตุใดจึงต้องใช้ Tee ถ้าคุณสามารถเรียกใช้คำสั่งที่คล้ายกันสองครั้งได้
ในตัวอย่างข้างต้น คุณไม่จำเป็นต้องใช้ tee หากสามารถรัน ls
ตามปกติแล้วรันอีกครั้งและเปลี่ยนเส้นทางเอาต์พุตไปยังไฟล์ อย่างไรก็ตาม คุณจะพบกับสถานการณ์ที่ผลลัพธ์จะไม่ซ้ำกัน ลองนึกภาพสถานการณ์ที่คุณพยายามวินิจฉัยปัญหา คุณเรียกใช้ diagnose | tee error.log
. ข้อผิดพลาดที่คุณได้รับอาจไม่ซ้ำกัน คุณต้องการให้แสดงบนหน้าจอเพื่อให้คุณสามารถดูว่าเกิดอะไรขึ้นเมื่อคุณทดสอบสิ่งต่างๆ แต่คุณต้องการบันทึกข้อผิดพลาดเหล่านั้นลงในไฟล์ด้วย ดังนั้นคุณจึงสามารถตรวจทานในภายหลังหรือวางผลลัพธ์ในฟอรัมสนทนาและถามผู้อื่นเกี่ยวกับข้อผิดพลาดนั้นได้
อีกสถานการณ์หนึ่งที่มักพบบ่อยเมื่อคุณต้องการ tee คือ:คุณต้องการเขียนเอาต์พุตของคำสั่งไปยังตำแหน่งที่เฉพาะผู้ใช้ root เท่านั้นที่สามารถอ่านหรือเขียนได้ สิ่งนี้ใช้ไม่ได้
/sbin/blkid > /root/somefile
จากนั้น คุณอาจคิดว่า “แน่นอน แค่ใช้ sudo!” และคุณจะประหลาดใจที่วิธีนี้ใช้ไม่ได้เช่นกัน:
sudo blkid > /root/somefile
นั่นเป็นเพราะว่าหลังจาก sudo blkid
ดำเนินการ คุณยังคงเข้าสู่ระบบในฐานะผู้ใช้ปกติที่ไม่ใช่รูท และเชลล์ของคุณ (มักจะทุบตี) พยายามเขียนไปยัง /root/somefile
ด้วยข้อมูลประจำตัวผู้ใช้ปกติของคุณ ในการแก้ปัญหานี้ คุณสามารถใช้ tee:
/sbin/blkid | sudo tee /root/somefile
ข้อผิดพลาดในการต่อท้ายข้อความและการเปลี่ยนเส้นทาง
tee เป็นคำสั่งที่มีประโยชน์แต่เรียบง่าย command | tee somefile
จะเพียงพอเกือบทุกครั้ง อย่างไรก็ตาม มีสองสถานการณ์ที่คุณอาจพบซึ่งจำเป็นต้องใช้เคล็ดลับเหล่านี้
สิ่งแรกที่ต้องรู้คือทีนั้น โดยค่าเริ่มต้น จะเขียนทับไฟล์เสมอ หากคุณวิ่ง
ls | tee somefile
แล้วก็
ls /tmp | tee somefile
คำสั่งที่สองจะเขียนทับเนื้อหาของ somefile และคุณจะเห็นเฉพาะเนื้อหาของคำสั่งสุดท้ายที่ดำเนินการ หากต้องการเปลี่ยนพฤติกรรมนี้ คุณสามารถสร้างทีต่อท้ายข้อความแทนการเขียนทับได้ ในการทำเช่นนั้น เพียงใช้ -a
สวิตช์คำสั่ง
ls | tee -a somefile
สิ่งที่สองที่ควรทราบคือเอาต์พุตทั้งหมดไม่เหมือนกัน ข้อความแสดงข้อผิดพลาดจะได้รับการปฏิบัติแตกต่างกัน และถึงแม้จะปรากฏบนหน้าจอ แต่ก็ไม่ถือว่าเป็น stdout จึงไม่โดนทีออฟจับได้ (ถือว่าเป็น stderr) นี่คือตัวอย่างเกี่ยวกับ grep
grep -r L2TP /etc | tee somefile
มันจะแสดงบางอย่างเช่นภาพต่อไปนี้
ข้อความปฏิเสธการอนุญาตจะถูกเขียนไปยัง stderr สิ่งเดียวที่เขียนถึง stdout คือข้อความที่ไฮไลต์ นั่นเป็นเหตุผลที่คุณจะสังเกตเห็นว่าเนื้อหาของ “somefile” คือสิ่งที่แสดงในภาพด้านล่าง
ในกรณีนี้ เมื่อใช้ grep เพื่อค้นหาข้อความ จะมีประโยชน์ที่ข้อความแสดงข้อผิดพลาดจะไม่ถูกเปลี่ยนเส้นทางไปยังไฟล์ พวกเขาจะเติมไฟล์ด้วยขยะที่ไม่จำเป็น คุณต้องการดูผลลัพธ์ที่พบเท่านั้น แต่เมื่อคุณต้องการข้อความแสดงข้อผิดพลาด ให้ใช้ 2>&1
ซึ่งเปลี่ยนเส้นทาง stderr ไปที่ stdout
grep -r L2TP /etc 2>&1 | tee somefile
ด้วยคำสั่งนี้ คุณจะสังเกตเห็นว่าขณะนี้ somefile มีข้อความแสดงข้อผิดพลาดด้วย
บทสรุป
หวังว่าบทช่วยสอนนี้จะครอบคลุมทุกสิ่งที่คุณต้องการเพื่อให้ได้รับประโยชน์สูงสุดจากคำสั่ง tee แต่ถ้าคุณเจอสถานการณ์ที่ติดอยู่กับที แสดงความคิดเห็นด้านล่าง แล้วเราอาจช่วยได้