Fiquei com um comportamento estranho do comando readarray.
O man bash afirma:
readarray Read lines from the standard input into the indexed array variable array
mas esses scripts não funcionam (a matriz está vazia):
unset arr; (echo a; echo b; echo c) | readarray arr; echo ${#arr[@]} unset arr; cat /etc/passwd | readarray arr; echo ${#arr[@]}
E isso funciona:
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[@]}
O que há de errado com o tubo?
Resposta
Talvez tente:
unset arr printf %s\\n a b c | { readarray arr echo ${#arr[@]} }
Espero que funcione , mas no momento em que você sai do último { shell ; } contexto no final do | pipeline lá você perderá o valor da variável. Isso ocorre porque cada um dos | processos | separados em um | pipeline é executado em um ( subshell ). Portanto, sua coisa não funciona pelo mesmo motivo:
( arr=( a b c ) ) ; echo ${arr[@]}
… não “t – o valor da variável foi definido em um diferente / em> processo shell do que aquele em que você o chama.
Resposta
Para garantir o readarray comando é executado no shell atual, use a substituição do processo no lugar do pipeline:
readarray -t arr < <( echo a; echo b; echo c )
ou (if bash 4.2 ou posterior) use a opção de shell lastpipe:
shopt -s lastpipe ( echo a; echo b; echo c ) | readarray -t arr
Comentários
Resposta
readarray também pode ler stdin, então:
readarray arr <<< "$(echo a; echo b; echo c)"; echo ${#arr[@]}
< <2 setas?bash. Em suma, é a sintaxe ' para tratar um pipeline como um descritor de arquivo.< <(...)significa redirecionar a entrada (o primeiro<) da saída do comando dentro de<(...). Da mesma forma,> >(...)passaria a saída padrão para a entrada padrão do pipeline dentro de>(...). Você não ' não precisa necessariamente usar o redirecionamento com substituição de processo.cat <( echo a b c )também funciona.readarray -t arr. Deman bash:-t Remove a trailing newline from each line read.bash5.0.17 e isso não ' não funciona para mim. Eu ' verifiqueiBASHOPTSe contémlastpipe, mascat myfile.txt | readarray -t arrfornece umarrvazio, masreadarray -t arr < <(cat myfile.txt)funciona corretamente.