Обнаружено через комментарий @rampion:
Что происходит, так это то, что ядро обрабатывает первый два символа файла, ищущего # !. Если они найдены, он пропускает все символы пробела , ища непробельный символ, и извлекает путь интерпретатора , который должен быть реальным исполняемым файлом, а не другим скриптом , хотя linux расширяет это, чтобы разрешить рекурсивную обработку скрипта . Обнаружив, что затем он переходит к первому непробельному символу , откуда переходит к следующему символу новой строки, а передает его как один аргумент команде. Нет никакой "оболочки" обработки кавычек или других метасимволов. Это все очень просто и грубо. Поэтому вы не можете вникнуть в там с параметрами. Вы получаете ровно один аргумент, включающий пробел, и 'perl -w' - это то, что ядро видит здесь и передает дальше.
Источник: http://lists.gnu.org/archive/html/bug-sh-utils/2002-04/msg00020.html
Один из способов думать об этом — представить, что local var1="local 1"
сохраняет текущее значение var1
с обещанием, что в конце функции оно будет восстановлено, а затем устанавливает его в "local 1"
. С помощью этой ментальной модели вы можете думать обо всех переменных как о глобальных, а переменные восстанавливаются в конце функций.
Пример был бы лучше, если бы вместо вызова echo как внутри функции, так и снаружи вызывалась другая функция, которая вывела var
.
bash$ show(){ printf " The value of %s in %s is '%s'\n" $1 $2 ${!1} ; }
bash$ bar(){ show v1 bar_$1 ; }
bash$ foo(){ show v1 before_foo ; local v1 ; show v1 after_local ; \
v1="changed"; show v1 after_change ; bar via_foo ; }
bash$ v1="global"
bash$ show v1 global_scope
The value of v1 in global_scope is 'global'
bash$ foo
The value of v1 in before_foo is 'global'
The value of v1 in after_local is ''
The value of v1 in after_change is 'changed'
The value of v1 in bar_via_foo is 'changed'
bash$ bar direct
The value of v1 in bar_direct is 'global'
bash$ show v1 global_scope
The value of v1 in global_scope is 'global'
Здесь вы можете видеть, что вызов bar изнутри foo получает значение v1, которое было установлено foo.
Поиск в Интернете по словам dynamic scope
и lexical scope
может помочь.
В Bash локальные переменные должны вызываться явно, иначе они будут рассматриваться как глобальные. Даже внутри функций (, где применяется область действия ).
И какая бы область видимости ни была установлена в последний раз для переменной --, будь то локальная, через явное объявление слова local
, или глобальная через опущение --, будет возвращаться то, что возвращается во время ее вызова через echo
.
Итак, в вашем примере после вызова функции локальная область видимости устанавливается на var1
, поэтому любые изменения этой переменной не сохраняются за пределами функции. Но глобальный остается установленным на var2
, так что изменения в этой переменной остаются.