Me quedé con un comportamiento extraño del comando readarray
.
El man bash
dice:
readarray Read lines from the standard input into the indexed array variable array
pero estos scripts no funcionan (la matriz está vacía):
unset arr; (echo a; echo b; echo c) | readarray arr; echo ${#arr[@]} unset arr; cat /etc/passwd | readarray arr; echo ${#arr[@]}
Y estos funcionan:
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[@]}
¿Qué pasa con la tubería?
Respuesta
Tal vez intente:
unset arr printf %s\\n a b c | { readarray arr echo ${#arr[@]} }
Espero que funcione , pero en el momento en que sales de ese último contexto {
shell ; }
al final del |
pipeline allí perderá el valor de su variable. Esto se debe a que cada uno de los |
procesos |
separados dentro de una |
se ejecuta en una (
subshell )
. Así que lo tuyo no funciona por la misma razón:
( arr=( a b c ) ) ; echo ${arr[@]}
… no «t – el valor de la variable se estableció en un diferente proceso de shell que en el que lo invocas.
Responder
Para garantizar la se ejecuta en el shell actual; utilice la sustitución del proceso en lugar de la canalización:
readarray -t arr < <( echo a; echo b; echo c )
o (si bash
4.2 o posterior) use la lastpipe
opción de shell:
shopt -s lastpipe ( echo a; echo b; echo c ) | readarray -t arr
Comentarios
Respuesta
readarray
también puede leer desde stdin, por lo que:
readarray arr <<< "$(echo a; echo b; echo c)"; echo ${#arr[@]}
< <
2 flechas?bash
página de manual. En resumen, es la sintaxis ' s para tratar una canalización como un descriptor de archivo.< <(...)
significa redirigir la entrada (la primera<
) de la salida del comando dentro de<(...)
. De manera similar,> >(...)
pasaría la salida estándar a la entrada estándar de la canalización dentro de>(...)
. No ' no es necesario que utilice la redirección con sustitución de procesos.cat <( echo a b c )
también funciona.readarray -t arr
. Deman bash
:-t Remove a trailing newline from each line read.
bash
5.0.17 y esto no ' me funciona. ' incluso he comprobadoBASHOPTS
y contienelastpipe
, perocat myfile.txt | readarray -t arr
da unarr
vacío, peroreadarray -t arr < <(cat myfile.txt)
funciona correctamente.