แสดง STDOUT ก่อน STDERR หรือไม่


9

ฉันใหม่เพื่อทุบตีและฉันไม่สามารถให้ชีวิตของฉันคิดออกวิธีการเรียกใช้คำสั่งบางอย่างสมมติ./fffและพิมพ์ stdouts ปกติก่อน stderr (ฉันสับสนเกี่ยวกับความหมายของตัวเอง)

ตัวอย่างเช่น

$ printf "I am a\ndrill\n" > fff; 
$ cat fff nofile fff nofile fff

I am a
drill
cat: nofile: No such file or directory
I am a
drill
cat: nofile: No such file or directory
I am a
drill

ต้องการพิมพ์เช่น:

I am a
drill
I am a
drill
I am a
drill
cat: nofile: No such file or directory
cat: nofile: No such file or directory

ฉันเข้าใจว่าฉันต้องเปลี่ยนเส้นทางผลลัพธ์ของฉันก่อนเป็นไฟล์จากนั้นจึงผนวกข้อผิดพลาดไปยังไฟล์เดียวกัน แต่นี่คือผลลัพธ์ที่ฉันได้รับ

$ cat ./foo nofile ./foo nofile ./foo <<< $(touch fin) > see 2>> see 

I am a
drill
I am a
drill
I am a
drill
ectory
cat: nofile: No such file or directory

2
ไม่catจริงๆแทนที่ "เป็น" โดย "บางคน"?
Dmitry Grigoryev

โอ้แดงฉันอาจทำให้สตริงยุ่ง ฉันจะแก้ไขทันที @DmitryGrigoryev
MeOw

คำตอบ:


18

คุณจะต้องเก็บเอาต์พุต stderr ไว้ที่ใดที่หนึ่งเพื่อให้สามารถแสดงได้ในตอนท้าย

ไฟล์มาถึงใจ:

fff 2> file; cat file >&2

หรือหน่วยความจำ (ที่นี่ใช้spongeจากmoreutils):

{ fff 2>&1 >&3 3>&- | sponge >&2 3>&-; } 3>&1
  • {...} 3>&1: ภายใน{...}file descriptor (fd) 3 คะแนนจากแหล่งข้อมูลเดียวกันกับstdout ดั้งเดิม (เพื่อให้เราสามารถใช้เพื่อเรียกคืน stdout ได้fff)
  • fff <redirs> | sponge <redirs>, fffและspongeเริ่มต้นพร้อมกัน (กับ<redirs>นำไปใช้เป็นอิสระ) กับfff's stdout ไปท่อและsponge' s stdin เป็นส่วนอื่น ๆ ของท่อ
  • 2>&1: fd 2 จากfff(stderr) ชี้ไปที่สิ่งเดียวกันกับวันที่ 1: ไปป์ที่จุดนี้ดังนั้นfffข้อผิดพลาดจึงไปspongeผ่านทางไปป์นั้น
  • >&3: ตอนนี้ stdout ชี้ไปที่ stdout ดั้งเดิม (เปลี่ยนเส้นทางกลับไปที่เดิม)
  • 3>&-: เราปิด fd 2 ซึ่งfffไม่ต้องการ
  • spongeสะสมอินพุตและแสดงเฉพาะ (บน stdout ซึ่งถูกเปลี่ยนเส้นทาง>&2ไปยังทรัพยากรเดียวกันกับ stderr) หลังจากตรวจพบ eof บน stdin (สันนิษฐานว่าเป็นเมื่อfffสิ้นสุดและเขียนเอาต์พุตทั้งหมดบน stdout แล้ว)

ถ้าไม่ได้ติดตั้งคุณสามารถแทนที่ด้วยsponge perl -0777 -pe ''ด้วย-pe ''ให้perlอ่านหนึ่งระเบียนในแต่ละครั้งจากอินพุตและเขียนลง stdout -0777เป็นโหมด slurp ที่บันทึก (หนึ่งเดียวในกรณีนั้น) คืออินพุตทั้งหมด


กรุณาทำลายมันลงถ้าคุณมีเวลา!
George Udosen

เราสามารถใช้teeแทนsponge...
George Vasiliou

@GeorgeUdosen ดูการแก้ไข
Stéphane Chazelas

1
@GeorgeVasiliou teeไม่ได้เก็บข้อมูลมันเขียนมันทันทีที่อ่าน
Stéphane Chazelas

2
@MeOw: ไม่เป็นไร แต่เมื่อคำตอบของStéphaneบรรทัดที่สามแสดงขึ้นมาคุณไม่จำเป็นต้องบันทึก stdout; cat foo nofile foo nofile foo 2> ferr.txt; cat ferr.txtเพียงแค่ทำ (และคุณอาจไม่ต้องการใช้>>) นอกจากนี้Stéphaneยังเป็นจุดที่ยอดเยี่ยมที่คุณควรทำcat ferr.txt >&2เพื่อเขียนข้อมูล stderr ไปยัง stderr
G-Man กล่าวว่า 'Reinstate Monica'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.