रीडअरे (या पाइप) समस्या


19

मैं readarrayआदेश के एक अजीब व्यवहार के साथ फंस गया।

man bashस्टेट्स:

readarray
     Read lines from the standard input into the indexed array variable array

लेकिन ये स्क्रिप्ट काम नहीं करती हैं (सरणी खाली है):

unset arr; (echo a; echo b; echo c) | readarray arr; echo ${#arr[@]}
unset arr; cat /etc/passwd | readarray arr;  echo ${#arr[@]}

और ये काम:

unset arr; readarray arr < /etc/passwd ;  echo ${#arr[@]}
unset arr; mkfifo /tmp/fifo; (echo a; echo b; echo c) > /tmp/fifo & mapfile arr < /tmp/fifo ; echo ${#arr[@]}

पाइप में क्या खराबी है?

जवाबों:


15

शायद कोशिश करें:

unset arr
printf %s\\n a b c | {
    readarray arr
    echo ${#arr[@]}
}

मुझे उम्मीद है कि यह काम करेगा, लेकिन जिस क्षण आप पाइपलाइन के अंत में उस अंतिम {शेल ; }संदर्भ से बाहर निकलेंगे, |आप अपना चर मान खो देंगे। ऐसा इसलिए है क्योंकि एक पाइप लाइन के भीतर प्रत्येक |अलग-अलग |प्रक्रियाओं |को एक (उपधारा में निष्पादित किया जाता है )। तो आपकी बात उसी कारण से काम नहीं करती है:

( arr=( a b c ) ) ; echo ${arr[@]}

... नहीं - वैरिएबल वैल्यू को एक अलग शेल प्रक्रिया में सेट किया गया था जिसमें आप उस पर कॉल करते हैं।


23

readarrayवर्तमान शेल में कमांड निष्पादित करने के लिए , या तो पाइपलाइन के स्थान पर प्रक्रिया प्रतिस्थापन का उपयोग करें:

readarray arr < <( echo a; echo b; echo c )

या अगर bash 4.2 या बाद में) lastpipeशेल विकल्प का उपयोग करें :

shopt -s lastpipe
( echo a; echo b; echo c ) | readarray arr

1
ठंडा। यह काम करता है, लेकिन वास्तव में प्रक्रिया प्रतिस्थापन क्या है? और < <2 तीरों का क्या मतलब है ?
CMCDragonkai

1
bashमैन पेज देखें । संक्षेप में, यह एक फाइल डिस्क्रिप्टर के रूप में एक पाइपलाइन के इलाज के लिए वाक्यविन्यास है। अंदर के आउटपुट से < <(...)इनपुट (पहले <) को पुनर्निर्देशित करने का मतलब है <(...)। सिमिलरी, > >(...)मानक आउटपुट को पाइप लाइन के मानक इनपुट के अंदर पारित करेगा >(...)। जरूरी नहीं कि आप प्रक्रिया प्रतिस्थापन के साथ पुनर्निर्देशन का उपयोग करें। cat <( echo a b c )साथ ही काम करता है।
Chepner

ये दोनों विकल्प मेरे लिए एक अवांछनीय परिणाम उत्पन्न करते हैं, जहां प्रत्येक सरणी आइटम प्रत्येक स्ट्रिंग के अंत में लाइन अंत को बनाए रखता है। जबकि smac89 के जवाब से यह समस्या नहीं है।
thnee

3

readarray स्टडिन से भी पढ़ सकते हैं, इसलिए:

readarray arr <<< "$(echo a; echo b; echo c)"; echo ${#arr[@]}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.