lastpipe: как Bash меняет поведение последней команды в pipelineОдна из особенностей Bash - команды в pipeline обычно выполняются в отдельных subshell. Из-за этого переменные, изменённые внутри
while, после цикла могут не сохраниться.Например:
count=0
printf '%s\n' a b c |
while read -r line; do
((count++))
done
echo "$count"
В некоторых случаях результатом будет
0.Но у Bash есть настройка
lastpipe, которая меняет это поведение.▪️Включаем
lastpipeshopt -s lastpipe
Теперь последняя команда pipeline может выполняться в текущем shell.
count=0
printf '%s\n' a b c |
while read -r line; do
((count++))
done
echo "$count"
При подходящих условиях получим:
3▪️Есть важное условие
lastpipe работает только когда job control отключён:set +m
shopt -s lastpipe
Именно поэтому поведение может отличаться между интерактивным Bash и обычным скриптом.
▪️Проверить настройку
shopt lastpipe
Получим:
lastpipe off
или:
lastpipe on
▪️Почему это не универсальная замена
Вместо изменения поведения shell часто проще использовать редирект:
while read -r line; do
((count++))
done < <(printf '%s\n' a b c)
Так код не зависит от настройки
lastpipe.▪️Где
lastpipe действительно интересенЭто полезно знать при разборе чужих Bash-скриптов: одна и та же конструкция с pipeline может вести себя по-разному в зависимости от настроек shell и режима job control.
lastpipe - хороший пример того, как небольшая опция Bash меняет фундаментальное поведение pipeline и область видимости изменений.BashTex 📱 #bash #linux