Классическая ловушка Bash:
count=0
cat file.txt | while read -r line; do
((count++))
done
echo "$count"
Ожидание: увидим количество строк.
Реальность: 0.
▪️ Что произошло
Когда while read стоит справа от пайпа, цикл часто выполняется в subshell - дочернем процессе. То есть переменная count меняется не в текущем shell, а в его копии. После окончания цикла изменения исчезают.
▪️ Как делать правильно. Вариант 1: редирект файла вместо pipe
count=0
while IFS= read -r line; do
((count++))
done < file.txt
echo "$count"
Теперь цикл работает в текущем shell, и count сохраняется.
Вариант 2: process substitution. Если источник - команда, а не файл:
count=0
while IFS= read -r line; do
((count++))
done < <(grep ERROR app.log)
echo "$count"
<(...) подставляет вывод команды как файл, без subshell-проблемы в самом цикле.▪️ Почему это важно
Ломаются не только счетчики. Точно так же исчезают:, массивы, флаги, накопленные строки и любые переменные, измененные внутри цикла
BashTex 📱 #bash