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.
bash
5.0.17 e isso não ' não funciona para mim. Eu ' verifiqueiBASHOPTS
e contémlastpipe
, mascat myfile.txt | readarray -t arr
fornece umarr
vazio, masreadarray -t arr < <(cat myfile.txt)
funciona corretamente.