bash: echo: write error: Cuộc gọi hệ thống bị gián đoạn


9

Tôi muốn tạo một danh sách được sắp xếp với tất cả các số có 8 chữ số - từ 00000000 đến 99999999. Tôi đã nhập vào trình bao:

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

phản hồi là

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

Tại sao tôi có ba lỗi này và result.txt không đúng định dạng?

tôi sử dụng

GNU bash, phiên bản 4.4.12 (1) -release (x86_64-pc-linux-gnu)

Debian GNU / Linux 9.6 (kéo dài)

Nhân Linux: 4.19.0 # 2 SMP Thu ngày 1 tháng 11 15:31:34 EET 2018 x86_64 GNU / Linux


2
Tôi không thể không cảm thấy cách làm này sẽ không hiệu quả hơn seq -w 0 99999999.
Kusalananda

1
Sau đó, câu hỏi không đầy đủ / không chính xác / viết xấu hoặc một cái gì đó khác. Bởi vì tập lệnh (khi hoàn thành với }) hoạt động chính xác. @ GAD3R
Isaac

1
Lưu ý: Tôi có thể kích hoạt các lỗi này gần như theo yêu cầu. Chúng thường xuất hiện khi tôi thay đổi kích thước konsolecửa sổ của tôi . Thay đổi kích thước như vậy là gần như đủ trong trường hợp của tôi, nhưng không cần thiết.
Kamil Maciorowski

Tôi có thể loại bỏ | tee result.txt, và vẫn nhận được lỗi.
ctrl-alt-delor

Một lưu ý khác: thực thi bên ngoài ( /bin/echotrong trường hợp của tôi) thay vì echodựng sẵn làm cho chức năng miễn dịch (hoặc ít nhất là ít bị ảnh hưởng hơn) đối với vấn đề này.
Kamil Maciorowski

Câu trả lời:


6

write error: Interrupted system callLỗi cụ thể được tạo khi kích thước cửa sổ giao diện điều khiển bị thay đổi trong khi tập lệnh đang được thực thi.

Làm một:

 trap '' SIGWINCH

sẽ tránh nó

Lưu ý rằng một

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

Sẽ nhanh hơn và sẽ tránh được SIGWINCHvấn đề.


5
Vì vậy, những gì đang xảy ra?, Tại sao tôi chưa thấy điều này trước đây? Tại sao là một lỗi viết, điều đúng đắn phải làm?
ctrl-alt-delor

4

Đây thực sự là một lỗi [1] trong bash, và nó không chỉ xảy ra trên SIGWINCH, mà còn trên bất kỳ tín hiệu mà một cái bẫy đã được thiết lập:

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

Điều này xảy ra do bashkhông thể a) đặt trình xử lý tín hiệu của nó với SA_RESTART(ngoại trừ SIGCHLDtrình xử lý) hoặc b) xử lý EINTRkhi gọi write()trong printfechonội trang.

EINTR("Cuộc gọi hệ thống bị gián đoạn") không phải là cách để chỉ ra tình trạng lỗi, nhưng là một hack cho phép lập trình viên kết hợp chặn đọc / ghi / vv với việc xử lý tín hiệu trong vòng lặp chính. Nó không bao giờ nên bị rò rỉ cho người dùng.

Lỗi này không xuất hiện quá thường xuyên bởi vì thật là kỳ công để có được điều kiện phù hợp: write()cần được thực hiện bởi một nội dung (không phải bằng lệnh bên ngoài), nó sẽ lấp đầy bộ đệm ống (đầu đọc khác kết thúc nên chậm hơn nhiều hoặc không đọc từ đường ống nhưng vẫn còn sống ) và tập lệnh nên sử dụng bẫy hoặc cửa sổ đầu cuối nên được thay đổi kích thước.

Và do các tạo phẩm triển khai đa dạng, điều này chỉ ảnh hưởng đến write()s bị gián đoạn , không phải read()s hoặc open()s (ví dụ như việc chặn open()đường ống có tên / fifo).

[1] một hình thức này đã được báo cáo một thời gian trước đây.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.