readarray (ou pipe)

19

Eu fiquei com um comportamento estranho do comando readarray .

Os estados man bash :

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 estes trabalhos:

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?

    
por dchirikov 09.06.2014 / 13:41

3 respostas

13

Talvez tente:

unset arr
printf %s\n a b c | {
    readarray arr
    echo ${#arr[@]}
}

Espero que funcione, mas no momento em que você sair do último contexto { shell ; } no final do | pipeline, você perderá seu valor variável. Isso ocorre porque cada um dos processos | separate | dentro de um | pipeline é executado em ( subshell ) . Então, sua coisa não funciona pelo mesmo motivo:

( arr=( a b c ) ) ; echo ${arr[@]}

... não - o valor da variável foi definido em um diferente processo shell do que aquele em que você invoca.

    
por 09.06.2014 / 13:47
22

Para garantir que o comando readarray seja executado no shell atual, use a substituição de processo no lugar do pipeline:

readarray arr < <( echo a; echo b; echo c )

ou (se bash 4.2 ou posterior) usar a opção lastpipe shell:

shopt -s lastpipe
( echo a; echo b; echo c ) | readarray arr
    
por 09.06.2014 / 14:55
2

readarray também pode ler stdin, então:

readarray arr <<< "$(echo a; echo b; echo c)"; echo ${#arr[@]}
    
por 11.11.2016 / 06:01

Tags