bash piping предотвращает глобальное присвоение переменных - PullRequest
5 голосов
/ 06 июня 2011
unset v
function f {
  v=1
}
f | cat
echo v=$v
f 
echo v=$v

Почему конвейер (для любой команды) не позволяет первой команде echo напечатать 1? Второй вывод эха 1. Я использую оболочку bash. Я могу увидеть это, скопировав / вставив или запустив это как скрипт.

1 Ответ

9 голосов
/ 06 июня 2011

Все компоненты конвейера (если их больше одного) выполняются в подоболочке, и их назначения переменных не сохраняются в основной оболочке.

Причина этого в том, что bash не поддерживает реальную многопоточность(с одновременным доступом к переменным), только подпроцессы, которые работают параллельно.


Как этого избежать :

Вы должны выполнять любые назначения переменных, которые вы хотитесохранить в main bash (или найти способ перенести их туда).Основным способом сделать это было бы не использовать канал, а вместо этого использовать подстановку процесса:

f > >( cat )

Конечно, это не поможет, если вам нужно назначать переменные в обоих процессах канала.Тогда вам нужно подумать о лучшем механизме (может быть, обрабатывать и выводить переменные куда-нибудь?)

...