Je suis coincé avec un comportement étrange de la commande readarray
.
Le man bash
indique:
readarray Read lines from the standard input into the indexed array variable array
mais ces scripts ne fonctionnent pas (le tableau est vide):
unset arr; (echo a; echo b; echo c) | readarray arr; echo ${#arr[@]} unset arr; cat /etc/passwd | readarray arr; echo ${#arr[@]}
Et ceux-ci fonctionnent:
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[@]}
Quel est le problème avec le tuyau?
Réponse
Peut-être essayer:
unset arr printf %s\\n a b c | { readarray arr echo ${#arr[@]} }
Je pense que cela fonctionnera , mais au moment où vous sortez de ce dernier {
shell ; }
contexte à la fin du |
pipeline là, vous perdrez la valeur de votre variable. En effet, chacun des processus |
|
séparés dans un pipeline |
est exécuté dans un (
sous-shell )
. Donc votre truc ne fonctionne pas pour la même raison:
( arr=( a b c ) ) ; echo ${arr[@]}
… doesn « t – la valeur de la variable a été définie dans un différent processus shell que celui dans lequel vous lappelez.
Réponse
Pour vous assurer que sexécute dans le shell actuel, soit utilisez la substitution de processus à la place du pipeline:
readarray -t arr < <( echo a; echo b; echo c )
ou (si bash
4.2 ou version ultérieure) utilisez loption shell lastpipe
:
shopt -s lastpipe ( echo a; echo b; echo c ) | readarray -t arr
Commentaires
Answer
readarray
peut également lire depuis stdin, donc:
readarray arr <<< "$(echo a; echo b; echo c)"; echo ${#arr[@]}
< <
2 flèches?bash
. En bref, cest la syntaxe ' pour traiter un pipeline comme un descripteur de fichier.< <(...)
signifie rediriger lentrée (le premier<
) de la sortie de la commande à lintérieur de<(...)
. De même,> >(...)
transmettrait la sortie standard à lentrée standard du pipeline à lintérieur de>(...)
. Vous navez ' pas nécessairement besoin dutiliser la redirection avec substitution de processus.cat <( echo a b c )
fonctionne également.readarray -t arr
. Depuisman bash
:-t Remove a trailing newline from each line read.
bash
5.0.17 et cela ne fonctionne pas ' pour moi. Jai ' même vérifiéBASHOPTS
et il contientlastpipe
, encorecat myfile.txt | readarray -t arr
donne unarr
vide, maisreadarray -t arr < <(cat myfile.txt)
fonctionne correctement.