Ik bleef bij een vreemd gedrag van readarray
commando.
De man bash
zegt:
readarray Read lines from the standard input into the indexed array variable array
maar deze scripts werken niet (array is leeg):
unset arr; (echo a; echo b; echo c) | readarray arr; echo ${#arr[@]} unset arr; cat /etc/passwd | readarray arr; echo ${#arr[@]}
En deze werken:
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[@]}
Wat is er mis met pipe?
Antwoord
Probeer misschien:
unset arr printf %s\\n a b c | { readarray arr echo ${#arr[@]} }
Ik verwacht dat het zal werken , maar op het moment dat u uit die laatste {
shell ; }
context stapt aan het einde van de |
pipeline daar verlies je je variabele waarde. Dit komt doordat elk van de |
afzonderlijke |
processen binnen een |
-pijplijn wordt uitgevoerd in een (
subshell )
. Dus jouw ding werkt niet om dezelfde reden:
( arr=( a b c ) ) ; echo ${arr[@]}
… niet “t – de waarde van de variabele is ingesteld in een verschillende shell-proces dan degene waarin u het aanroept.
Answer
Om ervoor te zorgen dat de readarray
commando wordt uitgevoerd in de huidige shell, ofwel gebruik procesvervanging in plaats van de pijplijn:
readarray -t arr < <( echo a; echo b; echo c )
of (if bash
4.2 of hoger) gebruik de lastpipe
shell-optie:
shopt -s lastpipe ( echo a; echo b; echo c ) | readarray -t arr
Reacties
Answer
readarray
kan ook lezen van stdin, dus:
readarray arr <<< "$(echo a; echo b; echo c)"; echo ${#arr[@]}
< <
2 pijlen te hebben?bash
man-pagina. Kortom, het is de ' syntaxis voor het behandelen van een pijplijn als een bestandsdescriptor.< <(...)
betekent het omleiden van invoer (de eerste<
) van de uitvoer van de opdracht binnen<(...)
. Op dezelfde manier zou> >(...)
standaarduitvoer doorgeven aan de standaardinvoer van de pijplijn binnen>(...)
. U hoeft niet ' per se omleiding te gebruiken met procesvervanging.cat <( echo a b c )
werkt ook.readarray -t arr
. Vanman bash
:-t Remove a trailing newline from each line read.
bash
5.0.17 en dit ' werkt niet voor mij. Ik ' heb zelfsBASHOPTS
gecontroleerd en het bevatlastpipe
, maarcat myfile.txt | readarray -t arr
geeft een legearr
, maarreadarray -t arr < <(cat myfile.txt)
werkt correct.