Проблема, описанная в исходном посте, не имеет ничего общего с косвенным расширением. Различие в поведении является результатом вызова разных оболочек в зависимости от того, «выполняется» или «из источника» скрипта. Эти различия обнаруживают основной недостаток c при получении оболочки из переменной $ SHELL, лежащей в основе дизайна скрипта. Если оболочка, определенная в $ SHELL, не соответствует shebang, сценарий завершится ошибкой либо при запуске, либо при выполнении. Далее следует объяснение.
Косвенное расширение не предлагает ценности в данном сценарии, потому что значения могут быть также легко присвоены напрямую. Они должны быть назначены таким образом независимо от синтаксиса, используемого для косвенного расширения между оболочками. На самом деле, другие различия синтаксиса между оболочками делают все предпосылки для обнаружения спорной оболочки! Однако, если оставить это в стороне, различие в поведении является результатом вызова разных оболочек в зависимости от того, «выполняется» или «из источника» скрипта. Поведение источника хорошо документировано с многочисленными объяснениями в Интернете, но для контекста вот как это работает:
Выполнение сценария Используйте синтаксис «./» для выполнения сценарий. При таком запуске скрипт выполняется в суб-оболочке. Любые изменения, которые скрипт вносит в свою оболочку, применяются к подоболочке, а не к оболочке, в которой был запущен скрипт, поэтому эти изменения теряются при выходе из оболочки, потому что подоболочка, в которой он выполняется, также уничтожается. Например, если сценарий изменяет рабочий каталог, это происходит во вспомогательной оболочке. Рабочий каталог основной оболочки, запустившей сценарий, не изменяется после завершения сценария. Если вы хотите внести изменения в оболочку, в которой был запущен сценарий, он должен иметь источник.
Источник сценария Используйте синтаксис «источник» для создания сценария. При запуске таким образом сценарий по сути становится аргументом исходной команды, которая обрабатывает вызов соответствующего выполнения. В некоторых оболочках (например, k sh) используется одна точка «.» вместо «source».
Когда сценарий выполняется с синтаксисом «./», shebang в верхней части файла используется для определения того, какую оболочку использовать. При получении сценария shebang игнорируется, и вместо него используется оболочка, в которой запускается сценарий. Также обратите внимание, что точка, которая появляется в синтаксисе команды «./», используемой для выполнения сценария, не связана с периодом, который иногда используется в качестве псевдонима для исходной команды.
В сценарии в сообщении используется bash в операторе shebang, поэтому он работает при выполнении, потому что запускается с использованием bash. Когда он получен из zsh, он обнаруживает неправильный синтаксис косвенного раскрытия:
“${!A_VAR}"
Правильный синтаксис:
"${(P)A_VAR}"
Однако исправление синтаксиса не поможет, потому что это затем завершится ошибкой при выполнении. Shebang вызовет bash, и синтаксис снова будет неправильным. Это делает косвенный доступ бесполезным для доступа к переменной, предназначенной для обозначения используемой оболочки. Что еще более важно, дизайн, основанный на запросе переменной среды для оболочки, ошибочен из-за различий в оболочке, которая в конечном итоге используется в зависимости от того, выполняется сценарий или источник.