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
переменной)
bash
while-loop
stdin
pipe
Вакан Танка
источник
источник
lastpipe
а также их плюсы и минусы.Ответы:
Правильная запись для подстановки процесса :
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
встроенную функцию, и один из многих ее вариантов:Таким образом, использование в скрипте чего-то вроде этого делает модифицируемый
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
Выполнение этого в командной строке обычно приводит к фолу «управление заданиями неактивно» (то есть в командной строке активно управление заданиями). Проверить это без использования сценария не удалось.
Кроме того, как отметил Гарет Рис в своем ответе , иногда вы можете использовать здесь строку :
while read i; do echo $i; done <<< "$FILECONTENT"
Это не требует
shopt
; вы можете сохранить процесс, используя его.источник
while read i; do echo $i; done < <(cat /etc/passwd); echo $i
он не возвращал последнюю строку два раза. Что я делаю не так?i
до пустого, поэтому эхо после цикла повторяет пустую строку.while read i; do x=$i; done < <(cat /etc/passwd); echo i=$i; echo x=$x
сработало, // может быть, в те дни поведение bash изменилось?Джонатан Леффлер объясняет, как делать то, что вы хотите, используя подстановку процесса , но другой вариант - использовать здесь строку :
while read i; do echo "$i"; done <<<"$FILECONTENT"
Это экономит процесс.
источник
Эта функция создает дубликаты файлов jpg в $ NUM раз (bash)
function makeDups() { NUM=$1 echo "Making $1 duplicates for $(ls -1 *.jpg|wc -l) files" ls -1 *.jpg|sort|while read f do COUNT=0 while [ "$COUNT" -le "$NUM" ] do cp $f ${f//sm/${COUNT}sm} ((COUNT++)) done done }
источник