CURL में त्रुटि क्यों आती है "(23) लिखने में विफल"?


153

यह एक उपकरण के रूप में ठीक काम करता है:

curl "someURL"
curl -o - "someURL"

लेकिन यह एक पाइपलाइन में काम नहीं करता है:

curl "someURL" | tr -d '\n'
curl -o - "someURL" | tr -d '\n'

यह रिटर्न:

(23) Failed writing body

CURL आउटपुट को पाइप करने में क्या समस्या है? पूरे CURL आउटपुट को कैसे बफर करें और फिर इसे हैंडल करें?


1
मेरे लिए यह काम करता है, बफर की जरूरत नहीं है।
hek2mgl

1
पाइप लाइन में भी यह काम करता है ?:curl 'http://www.multitran.ru/c/m.exe?CL=1&s=hello&l1=1' | tr -d '\n'
स्थिर

1
Osx टैग जोड़े गए। दुर्भाग्य से मैं इसके साथ मदद नहीं कर सकता। मैं लिनक्स का उपयोग कर रहा हूँ
hek2mgl

1
समस्या पृष्ठ की एन्कोडिंग थी (सिरिलिक, विन -1251)। तो मुझे उपयोग करना होगाiconv -f ...
स्थैतिक

5
बस एक और संकेत के रूप में: मेरा विफल रहा, क्योंकि डिस्क भरा हुआ था।
विंस वर्गा

जवाबों:


113

ऐसा तब होता है जब एक पाइप्ड प्रोग्राम (जैसे grep) पिछले प्रोग्राम को पूरा पेज लिखने से पहले रीड पाइप को बंद कर देता है।

में curl "url" | grep -qs foo, जैसे ही ग्रेप यह क्या चाहता है यह कर्ल से पढ़ा धारा बंद हो जाएगा है। CURL को इसकी उम्मीद नहीं है और "असफल लेखन निकाय" त्रुटि का उत्सर्जन करता है।

वर्कअराउंड एक मध्यस्थ प्रोग्राम के माध्यम से स्ट्रीम को पाइप करना है जो हमेशा अगले प्रोग्राम को खिलाने से पहले पूरे पृष्ठ को पढ़ता है।

उदाहरण के लिए

curl "url" | tac | tac | grep -qs foo

tacएक साधारण यूनिक्स प्रोग्राम है जो पूरे इनपुट पेज को पढ़ता है और लाइन ऑर्डर को उलट देता है (इसलिए हम इसे दो बार चलाते हैं)। चूँकि इसे अंतिम पंक्ति को खोजने के लिए पूरे इनपुट को पढ़ना पड़ता है, इसलिए यह कुछ भी उत्पन्न नहीं करेगा जब तक कि CURL समाप्त न हो जाए। Grep तब भी रीड स्ट्रीम को बंद कर देगा जब उसके पास वह है जो वह ढूंढ रहा है, लेकिन यह केवल tac को प्रभावित करेगा, जो एक त्रुटि का उत्सर्जन नहीं करता है।


5
क्या आप इसे केवल catएक बार के माध्यम से पाइप नहीं कर सकते ? मेरे लिए समस्या हल करता है, कम से कम।
बेन्वाड

5
नहीं। यह छोटे दस्तावेज़ों के साथ मदद कर सकता है, लेकिन जब बफर बिल्ली में फिट होने के लिए यह बहुत बड़ा होता है तो त्रुटि फिर से दिखाई देगी। आप -sसभी त्रुटि संदेशों (और प्रगति) को चुप करने के लिए उपयोग कर सकते हैं यदि आपको उनकी आवश्यकता नहीं है।
ककोरू

9
tac|tacइनपुट को बदल देता है यदि इनपुट लाइनफीड के साथ समाप्त नहीं होता है, या उदाहरण के लिए printf a\\nb\\nc|tac|tacप्रिंट्स a\ncbजहां \nएक लाइनफीड है। आप sponge /dev/stdoutइसके बजाय उपयोग कर सकते हैं । एक अन्य विकल्प है printf %s\\n "$(cat)", लेकिन जब इनपुट में Zsh के अलावा अन्य गोले में अशक्त बाइट्स होते हैं, जो या तो नल बाइट्स को छोड़ देता है या पहले नल बाइट के बाद पढ़ना बंद कर देता है।
निसेटमा

डॉक्स से: CURLE_WRITE_ERROR (23) स्थानीय फ़ाइल में डेटा प्राप्त करते समय कोई त्रुटि हुई, या राइटबैक कॉलबैक से एक त्रुटि libcurl में वापस आ गई थी। curl.haxx.se/libcurl/c/libcurl-errors.html
जॉर्डन स्टीवर्ट

3
इसका उत्तर स्वीकार किया जाना चाहिए क्योंकि यह समस्या की व्याख्या करता है, यह माना जाता है कि यह सक्षम समाधान प्रदान नहीं करता है क्योंकि macOS tacपर कोई आदेश नहीं है
डोमिनिक Bucher

49

पूर्णता और भविष्य की खोजों के लिए:

यह मामला है कि कैसे cURL बफर का प्रबंधन करता है, बफर -N विकल्प के साथ आउटपुट स्ट्रीम को निष्क्रिय करता है।

उदाहरण: curl -s -N "URL" | grep -q Welcome


8
इसने काम किया curl -s https://raw.githubusercontent.com/hermitdave/FrequencyWords/master/content/2016/ro/ro_50k.txt | head -20(बिना -sमुझे वही त्रुटि मिली)।
डेन डैस्कलेस्क्यू

24

एक अन्य संभावना, यदि -oआउटपुट (आउटपुट फ़ाइल) विकल्प का उपयोग कर रहा है - गंतव्य निर्देशिका मौजूद नहीं है।

जैसे। यदि आपके पास -o /tmp/download/abc.txtऔर / tmp / डाउनलोड मौजूद नहीं है।

इसलिए, यह सुनिश्चित करें कि पहले से मौजूद कोई भी आवश्यक निर्देशिका बनाई / मौजूद है, --create-dirsविकल्प का उपयोग करें - oयदि आवश्यक हो


2
धन्यवाद, --create-dirs ने मुझे सबसे असामान्य स्थिति में हल किया, यह कभी पता नहीं लगा सका कि क्या गलत था, लेकिन यह टिकट था!
rfay

1
ऐसा ही मेरे साथ भी हुआ। मैं आउटपुट के लिए चर $ को घोषित करना भूल गया। धन्यवाद, माइक।
मिनकांग हुआंग

8

तो यह एन्कोडिंग की समस्या थी। Iconv समस्या को हल करता है

curl 'http://www.multitran.ru/c/m.exe?CL=1&s=hello&l1=1' | iconv -f windows-1251 | tr -dc '[:print:]' | ...

8

आप -oविकल्प का उपयोग करने के बजाय ऐसा कर सकते हैं :

curl [url] > [file]


इसलिए, पाइप का उपयोग नहीं करते हैं और इसके बजाय फाइल सिस्टम पर सभी काम करते हैं? मैं पाइप के साथ कर्ल के आउटपुट का उपयोग करना चाहता था।
स्थिर

6

मेरे पास एक ही त्रुटि थी लेकिन विभिन्न कारणों से। मेरे मामले में मेरे पास केवल 1GB स्थान के साथ विभाजन (tmpfs) था और मैं बड़ी फ़ाइल डाउनलोड कर रहा था जिसने आखिरकार उस विभाजन पर सभी मेमोरी भर दी और मुझे आपके समान त्रुटि मिली।


5

सर्वर मेरे मामले में, डिस्क स्थान से बाहर चला गया।

इसके साथ जांच करें df -k .

जब मैंने tacदो बार पाइपिंग की कोशिश की, तो मुझे डिस्क स्थान की कमी के बारे में सूचित किया गया था , जैसा कि अन्य उत्तरों में से एक में वर्णित है: https://stackoverflow.com/a/28879552/336694 । इसने मुझे त्रुटि संदेश दिखाया write error: No space left on device


मुझे एक कंटेनर के भीतर डिस्क स्थान से बाहर चलने के कारण एक ही त्रुटि मिली, किसी और के लिए भी एक ही मुद्दे को मारने से उनके कंटेनरों के भीतर जगह साफ हो सकती हैdocker system prune
डेव

2

Ubuntu पर वार्निश कैश स्थापित करने का प्रयास करते समय मुझे इस त्रुटि संदेश का सामना करना पड़ा। Google खोज ने मुझे यहां त्रुटि के लिए उतारा (23) Failed writing body, इसलिए एक समाधान पोस्ट किया जो मेरे लिए काम किया।

कमांड को रूट के रूप में चलाते समय बग का सामना किया जाता है curl -L https://packagecloud.io/varnishcache/varnish5/gpgkey | apt-key add -

समाधान apt-key addगैर रूट के रूप में चलाने के लिए है

curl -L https://packagecloud.io/varnishcache/varnish5/gpgkey | apt-key add -

1

यदि आप कुछ इसी तरह की कोशिश कर रहे हैं source <( curl -sS $url )और (23) Failed writing bodyत्रुटि प्राप्त कर रहे हैं , तो इसका कारण यह है कि प्रक्रिया प्रतिस्थापन सोर्सिंग bash 3.2(macOS के लिए डिफ़ॉल्ट) में काम नहीं करता है ।

इसके बजाय, आप इस समाधान का उपयोग कर सकते हैं।

source /dev/stdin <<<"$( curl -sS $url )"

0

मेरे लिए, यह अनुमति मुद्दा था। डॉकर रन को यूजर प्रोफाइल के साथ कहा जाता है लेकिन रूट कंटेनर के अंदर का उपयोगकर्ता है। इसका समाधान यह था कि कर्ल को / tmp से लिखा जाए क्योंकि उसके पास सभी उपयोगकर्ताओं के लिए अनुमति है, न कि केवल रूट।

मैंने -o विकल्प का उपयोग किया।

-o / tmp / file_to_download


-1

बाश और zsh (और शायद अन्य गोले) में, आप मक्खी पर एक फ़ाइल बनाने के लिए प्रक्रिया प्रतिस्थापन ( बाश / zsh ) का उपयोग कर सकते हैं, और फिर पाइपलाइन श्रृंखला में अगली प्रक्रिया के लिए उस इनपुट के रूप में उपयोग कर सकते हैं।

उदाहरण के लिए, मैं JUR आउटपुट को cURL से पार्स करने की कोशिश कर रहा था jqऔर less, लेकिन Failed writing bodyत्रुटि हो रही थी ।

# Note: this does NOT work
curl https://gitlab.com/api/v4/projects/ | jq | less

जब मैंने प्रक्रिया प्रतिस्थापन का उपयोग करके इसे फिर से लिखा, तो यह काम कर गया!

# this works!
jq "" <(curl https://gitlab.com/api/v4/projects/) | less

नोट: jqइनपुट फ़ाइल निर्दिष्ट करने के लिए अपने 2 वें तर्क का उपयोग करता है

बोनस: आप उपयोग कर रहे हैं jqमेरे जैसे और करना चाहते हैं colorized उत्पादन रखने में less, बजाय निम्न आदेश पंक्ति का उपयोग करें:

jq -C "" <(curl https://gitlab.com/api/v4/projects/) | less -r

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

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