Jeg sidder fast med en underlig opførsel af readarray kommando.
man bash siger:
readarray Read lines from the standard input into the indexed array variable array
men disse scripts fungerer ikke (arrayet er tomt):
unset arr; (echo a; echo b; echo c) | readarray arr; echo ${#arr[@]} unset arr; cat /etc/passwd | readarray arr; echo ${#arr[@]}
Og disse fungerer:
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[@]}
Hvad er der galt med rør?
Svar
Måske prøve:
unset arr printf %s\\n a b c | { readarray arr echo ${#arr[@]} }
Jeg forventer, at det vil fungere , men det øjeblik du træder ud af den sidste { shell ; } kontekst i slutningen af | pipeline der mister du din variable værdi. Dette skyldes, at hver af | separate | processer inden for en | pipeline udføres i en ( subshell ). Så din ting virker ikke af samme grund:
( arr=( a b c ) ) ; echo ${arr[@]}
… virker ikke – variabelværdien blev indstillet i en anden shell-proces end den, du kalder på den.
Svar
At sikre readarray kommando udføres i den aktuelle shell, brug enten proceserstatning i stedet for pipelinen:
readarray -t arr < <( echo a; echo b; echo c )
eller (hvis bash 4.2 eller nyere) brug lastpipe shell-indstillingen:
shopt -s lastpipe ( echo a; echo b; echo c ) | readarray -t arr
Kommentarer
Svar
readarray kan også læses fra stdin, så:
readarray arr <<< "$(echo a; echo b; echo c)"; echo ${#arr[@]}
< <2 pile?bashman-siden. Kort sagt er det ' s syntaks til behandling af en pipeline som en filbeskrivelse.< <(...)betyder at omdirigere input (den første<) fra output af kommandoen inde i<(...). Tilsvarende ville> >(...)sende standardoutput til standardindgangen på rørledningen inde i>(...). Du behøver ikke ' nødvendigvis bruge omdirigering med proceserstatning.cat <( echo a b c )fungerer også.readarray -t arr. Framan bash:-t Remove a trailing newline from each line read.bash5.0.17 og dette fungerer ikke ' for mig. Jeg ' har endda tjekketBASHOPTSog den indeholderlastpipe, alligevelcat myfile.txt | readarray -t arrgiver en tomarr, menreadarray -t arr < <(cat myfile.txt)fungerer korrekt.