Bash не поддерживает локальные переменные
Это не правда. Bash (и другие оболочки, включая dash - это одно из немногих расширений POSIX, которое есть) имеет ключевое слово local
для создания локальных переменных. Они просто по умолчанию глобальные, а рыба по умолчанию локальные.
Также, когда вы говорите «переменные среды», вы имеете в виду «экспортируемые» переменные, для которых требуется явный шаг «export» в оболочках posixy, а флаг «-x» или «--export» устанавливается на set
in рыба.
Я е. здесь есть две разные вещи - доступна ли эта переменная только в этой функции / блоке / что угодно, а не снаружи, и передается ли она потомкам , включая внешние процессы.
Являются ли локальные переменные просто переменными среды, но с чем-то дополнительным?
Неэкспортированные переменные - это что-то меньше . Они не передаются функции ОС setenv
, поэтому она не копирует их в дочерние процессы.
Локальные переменные удаляются по окончании блока. На практике это можно сделать красиво, положив их в стек и «вытолкнув» верх.
Обратите внимание, что, по крайней мере, у рыб эти понятия полностью ортогональны:
Вы можете иметь локально экспортируемые переменные (с set -lx
), и они будут переданы во внешние команды и скопированы в функции (чтобы они получили свою собственную локальную версию), но будут удалены после завершения функции. Это полезно, чтобы изменить что-то временное - например, установить $ PATH только для функции или переопределить $ EDITOR при вызове чего-либо.
И вы можете иметь глобально-неэкспортированные переменные, к которым могут обращаться функции, но не внешние команды. Они полезны для настроек оболочки, таких как $ fish_function_path, которая бесполезна для внешних инструментов, или $ COLUMN, которые могут даже сломать внешние инструменты при экспорте (потому что они начинают читать его, а не проверяют размер терминала самостоятельно).