ทำไมฉันไม่สามารถเปลี่ยนเส้นทางผลลัพธ์จาก awk ได้


0

ฉันได้เขียนรายการนี้เพื่อแสดงการอ่าน / เขียน MB ทุก 5 วินาที

#!/bin/bash
#iosum.sh
iostat -dmz 5 |\
    awk 'BEGIN{rx=wx=0}{if($0 == ""){printf"%.1f %.1f\n",rx,wx}else if($0~/^Device:/){rx=wx=0}else{rx+=$3;wx+=$4}}'

เมื่อทำงานจากบรรทัดคำสั่งมันทำงานได้อย่างสมบูรณ์

./iosum.sh
# wait
1.1 0.0
0.0 0.1
0.0 0.0
3.0 3.0
0.0 0.0
# ctrl-c

อย่างไรก็ตามเมื่อฉันพยายามใส่ผลลัพธ์ลงในไฟล์ฉันจะไม่ได้อะไรเลย

./iosum.sh > out.txt
# wait
# ctrl-c
cat out.txt
# nothing!

สิ่งที่ช่วยให้?

คำตอบ:


1

นี่เป็นปัญหาบัฟเฟอร์ Awk ทำงานแตกต่างกันไปขึ้นอยู่กับว่าเป็นแบบโต้ตอบหรือไม่ \nฟลัชบัฟเฟอร์เอาต์พุตในกรณีหลังเท่านั้นมิฉะนั้นตามที่คุณพบการบัฟเฟอร์จะเกิดขึ้นจนกว่าบัฟเฟอร์เอาต์พุตจะเต็มหรือถูกล้างด้วยคำสั่ง fflush อย่างชัดเจน

ในที่สุดจะมีบางอย่างในไฟล์เอาต์พุตถ้าคุณรอนานพอ

มิฉะนั้นเอาต์พุตควรถูกฟลัชหากคุณฆ่าiostatไม่ใช่สคริปต์

หรือนี่คือวิธีแก้ปัญหาง่ายๆ:

script -c iosum.sh out.txt

โปรดทราบว่าการปิดใช้งานการบัฟเฟอร์ (ด้วยscriptหรือชัดแจ้งfflush) กำลังส่งผลกระทบต่อประสิทธิภาพดังนั้นการฆ่าiostatกระบวนการ ( pkill -f "iostat -dmz 5") หรือการตั้งค่าให้ยุติหลังจากช่วงเวลาที่กำหนดเป็นวิธีที่ดีกว่าถ้าคุณไม่จำเป็นต้องตรวจสอบเนื้อหาไฟล์เช่นสอง ระยะเวลาการจับภาพนาที:

iostat -dmz 5 120 |\
    awk 'BEGIN{rx=wx=0}{if($0 == ""){printf"%.1f %.1f\n",rx,wx}else if($0~/^Device:/){rx=wx=0}else{rx+=$3;wx+=$4}}'

แน่นอนมันเป็นปัญหาบัฟเฟอร์ ฉันไม่รู้ว่าทำไมมันเป็นปัญหาบัฟเฟอร์ ... แต่การเพิ่มfflush(stdout)หลังจาก printf แก้ไขปัญหา
nullUser

จริง ๆ แล้วฉันกำลังไพพ์เอาท์พุทของสคริปต์นี้ไปยังแถบสถานะดังนั้นเอาท์พุทความต้องการที่จะเป็นทันที มันผลิตออกหนึ่งบรรทัดทุก ๆ 5 วินาทีนี่ส่งผลกระทบต่อประสิทธิภาพอย่างเห็นได้ชัดหรือไม่?
nullUser

ไม่ถูกต้อง อัตราห้าวินาทีคือการทำให้จุดของประสิทธิภาพการทำงานของฉัน moot มันจะเจ็บเฉพาะกับปริมาณงานที่สูง
jlliagre

0

Awk บัฟเฟอร์เอาต์พุตทั้งหมดและเขียนออกเมื่อเสร็จสิ้นอินพุตการอ่านหรือเมื่อบัฟเฟอร์เต็ม ใช้fflush(stdout)(ดูหน้า awk man) ในสคริปต์ awk ของคุณเพื่อให้แน่ใจว่าผลลัพธ์ถูกล้างออกไปยังดิสก์อย่างถูกต้องหลังจากพิมพ์ทุกบรรทัด แบบนี้:

iostat -dmz 5 |\
       awk 'BEGIN{rx=wx=0}{if($0 == ""){printf"%.1f %.1f\n",rx,wx;fflush(stdout)}else if($0~/^Device:/){rx=wx=0}else{rx+=$3;wx+=$4}}' > x
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.