Jag höll mig med ett konstigt beteende av readarray
kommando.
man bash
anger:
readarray Read lines from the standard input into the indexed array variable array
men dessa skript fungerar inte (arrayen är tom):
unset arr; (echo a; echo b; echo c) | readarray arr; echo ${#arr[@]} unset arr; cat /etc/passwd | readarray arr; echo ${#arr[@]}
Och dessa fungerar:
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[@]}
Vad är det för fel på röret?
Svar
Kanske försök:
unset arr printf %s\\n a b c | { readarray arr echo ${#arr[@]} }
Jag förväntar mig att det kommer att fungera , men när du går ut ur det sista {
skalet ; }
-kontext i slutet av |
pipeline där kommer du att förlora ditt variabla värde. Detta beror på att var och en av |
separata |
processer inom en |
pipeline körs i a (
subshell )
. Så din grej fungerar inte av samma anledning:
( arr=( a b c ) ) ; echo ${arr[@]}
… fungerar inte – variabelvärdet sattes i en annorlunda skalprocess än den där du anropar den.
Svar
För att säkerställa att readarray
kommandot körs i det aktuella skalet, använd antingen processersättning istället för pipelinen:
readarray -t arr < <( echo a; echo b; echo c )
eller (om bash
4.2 eller senare) använder lastpipe
skalalternativet:
shopt -s lastpipe ( echo a; echo b; echo c ) | readarray -t arr
Kommentarer
Svar
readarray
kan också läsas från stdin, så:
readarray arr <<< "$(echo a; echo b; echo c)"; echo ${#arr[@]}
< <
2 pilar?bash
mansidan. Kort sagt ' s syntax för att behandla en pipeline som en filbeskrivare.< <(...)
betyder att omdirigera ingång (den första<
) från kommandos utgång inuti<(...)
. På samma sätt skulle> >(...)
skicka standardutdata till standardingången för rörledningen inuti>(...)
. Du behöver inte ' nödvändigtvis använda omdirigering med processersättning.cat <( echo a b c )
fungerar också.readarray -t arr
. Frånman bash
:-t Remove a trailing newline from each line read.
bash
5.0.17 och detta fungerar inte ' för mig. Jag ' har även markeratBASHOPTS
och den innehållerlastpipe
, ändåcat myfile.txt | readarray -t arr
ger en tomarr
, menreadarray -t arr < <(cat myfile.txt)
fungerar korrekt.