Zachoval jsem se podivným chováním příkazu readarray
.
Stavy man bash
:
readarray Read lines from the standard input into the indexed array variable array
, ale tyto skripty nefungují (pole je prázdné):
unset arr; (echo a; echo b; echo c) | readarray arr; echo ${#arr[@]} unset arr; cat /etc/passwd | readarray arr; echo ${#arr[@]}
A tyto práce:
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[@]}
Co je s potrubím špatně?
Odpověď
Možná zkuste:
unset arr printf %s\\n a b c | { readarray arr echo ${#arr[@]} }
Očekávám, že to bude fungovat , ale v okamžiku, kdy vystoupíte z posledního {
prostředí ; }
kontextu na konci |
pipeline tam ztratíte hodnotu proměnné. Je to proto, že každý z |
samostatných |
procesů v rámci |
kanálu je spuštěn v a (
subshell )
. Vaše věc tedy nefunguje ze stejného důvodu:
( arr=( a b c ) ) ; echo ${arr[@]}
… nefunguje – hodnota proměnné byla nastavena v jiném shell proces než ten, ve kterém na něj zavoláte.
Odpovědět
Zajistit readarray
příkaz se provádí v aktuálním prostředí, buď použijte místo potrubí nahrazení procesu:
readarray -t arr < <( echo a; echo b; echo c )
nebo (pokud bash
4.2 nebo novější) použijte lastpipe
možnost prostředí:
shopt -s lastpipe ( echo a; echo b; echo c ) | readarray -t arr
Komentáře
Odpověď
readarray
umí číst také ze stdin, takže:
readarray arr <<< "$(echo a; echo b; echo c)"; echo ${#arr[@]}
< <
2 šipky?bash
manuálovou stránku. Stručně řečeno, je to ' syntaxe pro zpracování kanálu jako deskriptoru souboru.< <(...)
znamená přesměrovat vstup (první<
) z výstupu příkazu uvnitř<(...)
. Podobně by> >(...)
předal standardní výstup na standardní vstup potrubí uvnitř>(...)
. ' nemusíte nutně používat přesměrování s nahrazením procesu.cat <( echo a b c )
funguje také.readarray -t arr
. Zman bash
:-t Remove a trailing newline from each line read.
bash
5.0.17 a to pro mě ' nefunguje. I ' jsem dokonce zkontrolovalBASHOPTS
a obsahujelastpipe
, přestocat myfile.txt | readarray -t arr
dává prázdnýarr
, alereadarray -t arr < <(cat myfile.txt)
funguje správně.