bash: echo: ข้อผิดพลาดในการเขียน: การเรียกระบบขัดจังหวะ


9

ฉันต้องการสร้างรายการที่เรียงลำดับด้วยตัวเลข 8 หลักทั้งหมด - จาก 00000000 ถึง 99999999 ฉันพิมพ์ในเชลล์:

f() {
 while IFS="" read -r line; do
   for i in {0..9}; do 
       echo "$line$i";
   done;
 done
}

echo | f | f | f | f | f | f | f | f | tee result.txt | wc -l

การตอบสนองคือ

bash: echo: write error: Interrupted system call
bash: echo: write error: Interrupted system call
bash: echo: write error: Interrupted system call
99998890

เหตุใดฉันจึงมีข้อผิดพลาดสามข้อนี้และ result.txt ที่ผิดรูปแบบ

ฉันใช้

GNU ทุบตีรุ่น 4.4.12 (1) - ปล่อย (x86_64-pc-linux-gnu)

Debian GNU / Linux 9.6 (ยืด)

เคอร์เนล Linux: 4.19.0 # 2 SMP พฤ 1 พ.ย. 15:31:34 EET 2018 x86_64 GNU / Linux


2
ฉันอดไม่ได้ที่จะรู้สึกว่าวิธีการทำเช่นนี้จะไม่มีประสิทธิภาพมากกว่าseq -w 0 99999999นี้
Kusalananda

1
ดังนั้นคำถามนั้นไม่สมบูรณ์ / ไม่ถูกต้อง / เขียนไม่ดีหรืออย่างอื่น เพราะสคริปต์ (เมื่อเสร็จสมบูรณ์ด้วย}) ทำงานอย่างถูกต้อง @ GAD3R
ไอแซค

1
หมายเหตุ: ฉันสามารถเรียกข้อผิดพลาดเหล่านี้ได้ตามต้องการ มักจะปรากฏเมื่อฉันปรับขนาดkonsoleหน้าต่าง การปรับขนาดดังกล่าวเกือบเพียงพอในกรณีของฉัน แต่ก็ไม่จำเป็น
Kamil Maciorowski

ฉันสามารถลบ| tee result.txtและยังได้รับข้อผิดพลาด
ctrl-alt-delor

หมายเหตุอื่น: ปฏิบัติการภายนอก ( /bin/echoในกรณีของฉัน) แทนechobuiltin ทำให้ฟังก์ชั่นภูมิคุ้มกัน (หรือมีแนวโน้มน้อยกว่า) กับปัญหานี้
Kamil Maciorowski

คำตอบ:


6

write error: Interrupted system callข้อผิดพลาดเฉพาะจะถูกสร้างขึ้นเมื่อขนาดหน้าต่างคอนโซลเปลี่ยนไปในขณะที่สคริปต์กำลังดำเนินการ

ทำ:

 trap '' SIGWINCH

จะหลีกเลี่ยงมัน

โปรดสังเกตว่า

 seq 99999999 >result.txt; wc -l <result.txt

จะมีทั้งเร็วขึ้นและจะหลีกเลี่ยงSIGWINCHปัญหา


5
แล้วจะเกิดอะไรขึ้นทำไมฉันไม่เห็นสิ่งนี้มาก่อนทำไมข้อผิดพลาดในการเขียนสิ่งที่ถูกต้องทำคืออะไร
ctrl-alt-delor

4

นี่เป็นข้อผิดพลาด[1]ในbashและมันไม่ได้เกิดขึ้นเฉพาะในSIGWINCHแต่ยังมีสัญญาณใด ๆ ที่กับดักถูกตั้งค่า:

{ pid=$BASHPID; trap : USR1; (sleep 1; kill -USR1 $pid) &
         printf %0100000d 1; } | sleep 3600
bash: printf: write error: Interrupted system call

มันเกิดขึ้นเพราะbashล้มเหลวในการ a) ตั้งค่าตัวจัดการสัญญาณด้วยSA_RESTART(ยกเว้นSIGCHLDตัวจัดการ) หรือ b) จัดการEINTRเมื่อเรียกwrite()ในprintfและechobuiltins

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

ข้อผิดพลาดนี้ไม่ปรากฏขึ้นบ่อยเกินไปเพราะมันค่อนข้างเป็นความสำเร็จที่จะได้รับเงื่อนไขที่ถูกต้อง: สิ่งที่write()ควรทำโดยbuiltin (ไม่ใช่คำสั่งภายนอก) มันควรเติมบัฟเฟอร์ท่อ (ผู้อ่านที่อื่น ๆ ) ปลายควรช้าลงมากหรือไม่อ่านจากไปป์เลยแต่ยังมีชีวิตอยู่ ) และสคริปต์ควรใช้กับดักหรือหน้าต่างเทอร์มินัลควรถูกปรับขนาด

และเนื่องจากมีการใช้สิ่งประดิษฐ์ที่หลากหลายสิ่งนี้จะส่งผลกระทบต่อการขัดจังหวะwrite()ของ s เท่านั้นไม่ใช่read()s หรือopen()s (เช่นการปิดกั้นopen()ของไปป์ที่มีชื่อ / fifo)

[1]รูปแบบนี้ได้รับการรายงานไปแล้วเมื่อไม่นานมานี้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.