Tee ไม่ได้รับผลลัพธ์ทั้งหมดจากไปป์


12

ฉันมีสคริปต์ดำเนินการคำสั่งเช่น:

export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH;./some_app -i $INDEX | tee $LOG
echo "Number of errors: $(grep "ERROR" $LOG | wc -l)"

teeปัญหาอาจจะอยู่ในท่อ ดูเหมือนจะไม่ได้รับผลลัพธ์ทั้งหมด เมื่อแอปพลิเคชันหยุดทำงานไม่กี่บรรทัดสุดท้ายของเอาต์พุต (โดยปกติจะเป็นแอปที่มีข้อผิดพลาดร้ายแรง) หายไป เมื่อฉันเรียกใช้แอพโดยไม่ต้องไปป์teeฉันก็เอามันออกมาได้

ฉันจะบังคับให้สคริปต์รอทีเพื่อประมวลผลเอาต์พุตทั้งหมดได้อย่างไร


มันใช้งานได้ไหมถ้าคุณทีมันเป็นไฟล์ไม่ใช่ stdout?
Pilot6

คำตอบ:


23

ข้อผิดพลาดร้ายแรงอาจเกิดขึ้นใน STDERR (2) ไม่ใช่ STDOUT (1) คุณสามารถเปลี่ยนเส้นทาง STDERR ไปยัง STDOUT ด้วย2>&1และจากนั้นไปป์ควรจับมันด้วย

./some_app -i $INDEX 2>&1 | tee $LOG

หากคุณมีปัญหาการบัฟเฟอร์ด้านบนคุณสามารถบังคับให้เข้าสู่สถานะที่ไม่มีข้อผิดพลาด:

stdbuf -o0 ./some_app -i $INDEX 2>&1 | tee $LOG

ดีเรากำลังเข้าใกล้ ตอนนี้ฉันเห็นว่าข้อผิดพลาดร้ายแรงกำลังถูกพิมพ์อยู่ แต่ก็ยังไม่เสร็จสมบูรณ์ บรรทัดที่มีข้อผิดพลาดจะสิ้นสุดลงตรงกลางและเอาต์พุต echo ยังคงดำเนินต่อไป ยังคงมีปัญหาบางอย่างกับการลบบัฟเฟอร์หรือเพียงแค่รอในส่วนนั้นให้เสร็จสมบูรณ์
Ladislav Mrnka

แก้ไข หายากในประสบการณ์ของฉันที่บางสิ่งบางอย่างลื่นไถลผ่านบัฟเฟอร์เมื่อออก แต่มันก็คุ้มค่าที่จะไป
Oli

1
ทำ! ขอบคุณ. ฉันอาจจะถามคำถามมากเกินไป แต่ไม่มีใครเข้าใจว่าทำไมฉันต้องปิดการบัฟเฟอร์เมื่อทำการไพพ์ไปยังกระบวนการอื่น
Ladislav Mrnka

@Oli เป็นคนดีมาก!
Pilot6

6

ตามปกติข้อความแสดงข้อผิดพลาดจะแสดงบน STDERR (ตัวอธิบายไฟล์ 2) คุณต้องเปลี่ยนเส้นทางทั้ง STDOUT และ STDERR ไปที่tee:

./some_app -i "$INDEX" |& tee "$LOG"

เมื่อคุณทำคุณเป็นเพียงการเปลี่ยนทิศไป./some_app -i $INDEX | tee $LOGtee

|& จะทำให้ทั้ง STDOUT และ STDERR ถูกเปลี่ยนเส้นทาง

หากคุณไม่สามารถเปลี่ยนเส้นทางเพียง STDOUT (เช่นเดิม):

./some_app -i "$INDEX" | tee "$LOG"

ในทางกลับกันหากคุณต้องการเปลี่ยนเส้นทางเฉพาะ STDERR:

./some_app -i "$INDEX" 2>&1 >/dev/null | tee "$LOG"
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.