Глобальная переменная сбрасывается, если цикл отправляет вывод в канал

Согласно страницам руководства bash(1), когда я запускаю следующее:

set -e
x=2
echo Start $x
while [ $((x--)) -gt 0 ]; do echo Loop $x; done | cat
echo End $x

Выход будет:

Start 2
Loop 1
Loop 0
End 2

После цикла (работает как подоболочка) переменная x сбрасывается до 2. Но если я удалю канал, x будет обновлен:

Start 2
Loop 1
Loop 0
End -1

Мне нужно изменить х, но мне тоже нужна труба. Есть идеи, как обойти эту проблему?

1 ответ

Решение

bash всегда (по крайней мере, с 4.2) запускает все не правые части конвейера в подоболочке. Если значение x Необходимо изменить в вызывающей оболочке, вы должны переписать свой код, чтобы избежать конвейера.

Один ужасно выглядящий пример:

# If you commit to one bash feature, may as well commit to them all:
#   Arithmetic compound: (( x-- > 0 ))
#   Process substitution: > >( cat )
while (( x-- > 0 )); do echo Loop $x; done > >( cat )
Другие вопросы по тегам