bash: echo: write एरर: इंटरप्टेड सिस्टम कॉल


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

मुझे ये तीन त्रुटियां और विकृत परिणाम क्यों मिले हैं।

मैं उपयोग करता हूं

GNU बैश, संस्करण 4.4.12 (1) -release (x86_64-pc-linux-gnu)

डेबियन जीएनयू / लिनक्स 9.6 (खिंचाव)

लिनक्स कर्नेल: 4.19.0 # 2 एसएमपी थू नवंबर 1 15:31:34 ईईटी 2018 x86_64 GNU / लिनक्स


2
मैं मदद नहीं कर सकता, लेकिन ऐसा करने का यह तरीका इससे अधिक कुशल नहीं होगा seq -w 0 99999999
Kusalananda

1
फिर सवाल अधूरा / गलत / बुरी तरह से लिखित या कुछ और है। क्योंकि स्क्रिप्ट (जब पूरी होती है }) सही तरीके से काम करती है। @ जीएडी 3 आर
इसहाक

1
नोट: मैं इन त्रुटियों को लगभग मांग पर ट्रिगर कर सकता हूं। वे अक्सर दिखाई देते हैं जब मैं अपनी konsoleखिड़की का आकार बदलता हूं । इस तरह का आकार बदलना मेरे मामले में लगभग पर्याप्त है, फिर भी आवश्यक नहीं है।
कामिल मैकियोरोस्की

मैं हटा सकता हूं | tee result.txt, और अभी भी त्रुटि प्राप्त कर सकता हूं ।
सीटीएल-एल्ट-डेलोर

एक और नोट: बाहरी निष्पादन योग्य ( /bin/echoमेरे मामले में) echoबिलिन के बजाय इस मुद्दे को फ़ंक्शन प्रतिरक्षा (या कम से कम कम प्रवण) बनाता है।
कामिल मैकियोरोस्की

जवाबों:


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()printfecho

EINTR("बाधित सिस्टम कॉल") एक त्रुटि स्थिति को इंगित करने का एक तरीका नहीं है, लेकिन एक हैक जो प्रोग्रामर को मुख्य लूप में संकेतों की हैंडलिंग के साथ अवरुद्ध रीड्स / राइट्स / आदि को संयोजित करने की अनुमति देता है। इसे कभी भी उपयोगकर्ता को लीक नहीं किया जाना चाहिए।

यह बग बहुत बार दिखाई नहीं देता है क्योंकि यह सही परिस्थितियों को प्राप्त करने के लिए काफी उपलब्धि है: write()एक बायिन द्वारा किया जाना चाहिए (बाहरी कमांड द्वारा नहीं), इसे पाइप बफर (दूसरे पर रीडर) को भरना चाहिए अंत बहुत धीमा होना चाहिए या पाइप से पढ़ना नहीं चाहिए, लेकिन अभी भी जीवित है ), और स्क्रिप्ट को जाल का उपयोग करना चाहिए या टर्मिनल विंडो को फिर से आकार देना चाहिए।

और विविध कार्यान्वयन कलाकृतियों के कारण, यह केवल बाधित write()एस को प्रभावित करता है , न कि read()एस या open()एस (जैसे open()नामांकित पाइप / पंद्रह का अवरोध ) को प्रभावित करता है ।

[१] इसका एक रूप कुछ समय पहले ही बताया गया था।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.