питання про читання (або трубу)


19

Я дотримувався дивної поведінки readarrayкоманди.

У man bashговорить:

readarray
     Read lines from the standard input into the indexed array variable array

але ці сценарії не працюють (масив порожній):

unset arr; (echo a; echo b; echo c) | readarray arr; echo ${#arr[@]}
unset arr; cat /etc/passwd | readarray arr;  echo ${#arr[@]}

І ці роботи:

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[@]}

Що не так з трубою?

Відповіді:


15

Можливо, спробуйте:

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

Я очікую, що це спрацює, але щойно ви вийдете з цього останнього контексту {оболонки ; }в кінці |трубопроводу, ви втратите значення змінної. Це пояснюється тим, що кожен з |окремих |процесів у |трубопроводі виконується в (підпакеті ). Отже, ваша справа не працює з тієї ж причини:

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

... ні - значення змінної було встановлено в іншому процесі оболонки, ніж у тому, в якому ви викликаєте.


23

Щоб переконатися, що readarrayкоманда виконується в поточній оболонці, використовуйте замість процесу замість конвеєра:

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

або (якщо bash4.2 або пізнішої версії) використовувати lastpipeваріант оболонки:

shopt -s lastpipe
( echo a; echo b; echo c ) | readarray arr

1
Класно. Це працює, але що саме таке процес заміщення? А що означає мати < <2 стрілки?
CMCDragonkai

1
Дивіться сторінку bashчоловіка. Коротше кажучи, це синтаксис трактування конвеєра як дескриптора файлів. < <(...)означає перенаправити вхід (перший <) з виходу команди всередину <(...). Подібний, передав > >(...)би стандартний вихід на стандартний вхід трубопроводу всередині >(...). Не обов’язково використовувати перенаправлення із заміною процесу. cat <( echo a b c )працює також.
чепнер

Обидва ці варіанти дають для мене небажаний результат, коли кожен елемент масиву зберігає закінчення рядка в кінці кожного рядка. Тоді як відповідь smac89 не має цієї проблеми.
Thnee

3

readarray Можна також читати зі stdin, так що:

readarray arr <<< "$(echo a; echo b; echo c)"; echo ${#arr[@]}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.