ฉันจะไปป์ stderr เป็น zsh ได้อย่างไร?


18

ในทุบตี:

$ echo hi 2>&1 1>/dev/null | cat
$

ขณะที่อยู่ใน zsh:

$ echo hi 2>&1 1>/dev/null | cat
hi
$

มีวิธีการไพพ์เฉพาะข้อผิดพลาดมาตรฐานขณะเปลี่ยนเส้นทางมาตรฐานหรือไม่

คำตอบ:


22

ด้วย zsh และด้วยmult_iosตัวเลือกเปิด (ตามค่าเริ่มต้น) ใน:

echo hi 2>&1 1>/dev/null | cat

1> /dev/null | catถูกมองว่าเป็นการเปลี่ยนเส้นทางหลายechostdout 's

ดังนั้นechostdout จึงถูกเปลี่ยนเส้นทางไปที่ทั้งสอง/dev/nullและไปป์ที่cat(เช่นถ้าใช้tee)

หากต้องการยกเลิกการเปลี่ยนเส้นทางหลายครั้งคุณสามารถทำได้:

echo hi 2>&1 >&- > /dev/null | cat

นั่นคือปิด stdout (ยกเลิกการ piping) ก่อนที่จะเปลี่ยนเส้นทาง /dev/null

หรือใช้กลุ่มคำสั่งหรือเชลล์ย่อยเช่น:

{echo hi 2>&1 1>/dev/null} | cat 
(echo hi 2>&1 1>/dev/null) | cat

ด้วยวิธีนี้echostdout ของจะถูกเปลี่ยนเส้นทางอย่างชัดเจนเพียงครั้งเดียว (การเปลี่ยนเส้นทางไปป์ถูกนำไปใช้กับกลุ่ม / subshell และสืบทอดโดยecho)

หรือคุณสามารถปิดการใช้งานmultiosทั้งหมด:

(setopt nomultios; echo hi 2>&1 > /dev/null | cat)

หรือคุณสามารถใช้การทดแทนกระบวนการแทนไพพ์:

echo hi 2> >(cat) > /dev/null

ระวังอย่างไรก็ตามเมื่อการควบคุมงานปิด (เช่นในสคริปต์) catกระบวนการจะทำงานแบบไม่พร้อมกัน (เหมือนเริ่มต้นด้วย&)


3
ขอบคุณ! (echo hi 2>&1 1>/dev/null) | catอีกวิธีหนึ่งที่จะได้รับรอบเป็น
Tavian Barnes

1
@TavianBarnes จุดดีขอบคุณ ฉันได้เพิ่มไปยังคำตอบเพื่อความสมบูรณ์ นอกจากนี้ยังทำงานกับกลุ่มคำสั่ง ( {echo...}|cat)
Stéphane Chazelas
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.