Давайте детально разберем эту команду и поймем, почему результат может быть неочевидным.
Инициализация переменной:
a=5
a
со значением 5 в текущей shell-сессииКонвейер (pipeline):
true | { true && a=10; }
|
(true) передает свой вывод (которого нет) команде справаГрупповая команда в фигурных скобках:
{ true && a=10; }
{ ...; }
- группа команд, выполняемая в текущем shell-контекстеЛогическое И (&&):
true && a=10
Subshell изоляция:
|
) неявно создает subshell для правой частиФигурные скобки vs подгруппа:
{ ...; }
обычно выполняется в текущем shell, но не когда часть конвейера( ... )
- всегда создает subshellВыполним команду и проверим значение:
$ a=5; true | { true && a=10; }; echo $a
5
Если бы мы хотели изменить a
в текущем shell:
Без конвейера:
$ a=5; { true && a=10; }; echo $a
10
Process Substitution (bash):
$ a=5; true | { true && a=10; } > >(cat); echo $a
10
Последняя команда в конвейере без subshell (zsh):
% a=5; true | { true && a=10; }; echo $a
10
Резюмируем: в bash при выполнении a=5; true | { true && a=10; }
переменная a
останется равной 5, потому что присваивание a=10
выполняется в подоболочке, созданной конвейером, и не влияет на родительский shell.