Подтвердить что ты не робот

Как подключить вход к циклу Bash while и сохранить переменные после завершения цикла

Bash позволяет использовать: cat <(echo "$FILECONTENT")

Bash также позволяют использовать: while read i; do echo $i; done </etc/passwd

для объединения предыдущих двух это можно использовать: echo $FILECONTENT | while read i; do echo $i; done

Проблема с последней заключается в том, что она создает суб-оболочку, и после того, как конец цикла while не будет доступен, переменная i больше не будет доступна.

Мой вопрос:

Как добиться чего-то вроде этого: while read i; do echo $i; done <(echo "$FILECONTENT") или другими словами: Как я могу быть уверенным, что i выживает во время цикла?

Обратите внимание, что мне известно о включении выражения while в {}, но это не решает проблему (представьте, что вы хотите использовать функцию while while и возвращать переменную i)

4b9b3361

Ответ 1

Правильная нотация Замена процесса:

while read i; do echo $i; done < <(echo "$FILECONTENT")

Последнее значение i, назначенное в цикле, доступно тогда, когда цикл завершается. Альтернативой является:

echo $FILECONTENT | 
{
while read i; do echo $i; done
...do other things using $i here...
}

Скобки - это операция группировки ввода-вывода и сами не создают подоболочку. В этом контексте они являются частью конвейера и поэтому выполняются как подоболочка, но это связано с |, а не с { ... }. Вы упомянули об этом в вопросе. AFAIK, вы можете сделать возврат изнутри внутри функции.


Bash также предоставляет shopt встроенный и один из его многочисленных вариантов:

lastpipe

Если установлено, а управление заданием не активно, оболочка запускает последнюю команду конвейера, не выполняемого в фоновом режиме в текущей среде оболочки.

Таким образом, использование такого типа в script делает modfied sum доступным после цикла:

FILECONTENT="12 Name
13 Number
14 Information"
shopt -s lastpipe   # Comment this out to see the alternative behaviour
sum=0
echo "$FILECONTENT" |
while read number name; do ((sum+=$number)); done
echo $sum

Выполнение этого в командной строке обычно выполняется с ошибкой "управление заданиями неактивно" (то есть в командной строке активен контроль заданий). Тестирование этого без использования script не удалось.

Кроме того, как отметил Гарет Рис в своем ответе , вы иногда можете использовать здесь строка:

while read i; do echo $i; done <<< "$FILECONTENT"

Для этого не требуется shopt; вы можете сохранить процесс, используя его.