Подтвердить что ты не робот

$ {BASH_SOURCE [0]} эквивалентен в zsh?

Название должно сказать все. Я ищу эквивалент ${BASH_SOURCE[0]} в zsh.

Примечание. Я продолжаю находить, что "$0 эквивалентен ${BASH_SOURCE[0]}" в Интернете, но это кажется ложным: $0 похоже, является именем исполняемой команды. (Это argv[0], что имеет смысл.) Повторяя $0 в моем script (.zshrc), получаем zsh для $0, что не совпадает с тем, что есть ${BASH_SOURCE[0]}. Фактически, ${BASH_SOURCE[0]} работает в zsh, за исключением внутренних .zshrc файлов.

Что я действительно делаю в моем .zshrc (это не работает):

echo ${BASH_SOURCE[0]}
source `dirname $0`/common-shell-rc.sh

Источник не работает ($0 is zsh), а echo выводит пустую строку.

Изменить: , по-видимому, для работы $0 мне нужно установить опцию FUNCTION_ARGZERO. Любой способ проверить, установлено ли это в script? (так что я могу временно установить его) Он, по-видимому, включен, если вы не установили nofunction_argzero, и он включен в моей оболочке. Все равно ничего не получаю за $0. (Я думаю, что b/c у меня нет функции.)

4b9b3361

Ответ 1

${BASH_SOURCE[0]} эквивалент в zsh равен ${(%):-%N}, NOT $0 (как сказал OP, последний не удался .zshrc)

Здесь % указывает на быстрое расширение значения, %N указывает "Имя файла script, sourced file, или функция оболочки, выполняемая в настоящий момент zsh,

который был запущен совсем недавно. Если его нет, это эквивалентно параметру $0. "(From man zshmisc)

Ответ 2

$0 является правильным. В исходном script это имя script, поскольку оно было передано встроенному . или source (поэтому, если параметр path_dirs установлен, вам может потребоваться выполнить $path искать, чтобы найти фактическое местоположение script).

.zshrc не используется, что объясняет, почему $0 не установлен на .zshrc. Вы все равно знаете имя файла и его местоположение: it ${ZDOTDIR-~}/.zshrc.

Ответ 3

${(%):-%x} является ближайшим zsh эквивалентным bash $BASH_SOURCEksh ${.sh.file}) - not $0.

Совет шляпы Хуэй Чжэн за предоставление ключевого указателя и справочной информации в его ответе.

Возвращает (потенциально относительный) путь к script,

  • независимо от того, является ли источник script источником или нет.
    • в частности, он также работает внутри файлов инициализации/профилей, таких как ~/.zshrc (в отличие от $0, который необъяснимо возвращает туда путь оболочки).
  • независимо от того, вызвана ли изнутри функция, определенная в script или нет (в отличие от $0, которая возвращает имя функции внутри функции).

Единственное отличие от $BASH_SOURCE, которое я обнаружил, заключается в следующем неясном сценарии, который может быть даже ошибкой (см. Zsh 5.0.5): внутри функции, вложенной внутри другой функции в исходный код script, ${(%):-%x} не возвращает замкнутый путь script, когда эта вложенная функция вызывается (снова) позже, после того, как она была получена (возвращает либо ничего, либо "zsh" ).


Фоновая информация на ${(%):-%x}:

  • (%):- вместо имени переменной в расширении параметра (переменной) (${...}) делает доступными escape-последовательности, которые обычно используются для представления экологической информации в строках, например, используемых в PS1 для определения строки, отображаемой в качестве основной интерактивной подсказки.

    • % является экземпляром флага расширения параметра, все из которых перечислены в man zshexpn под заголовком Parameter Expansion Flags.
  • %x является одной из управляющих последовательностей, которые могут использоваться в строках быстрого действия, и она функционирует так, как описано выше; существует гораздо больше, например %d для представления текущего каталога.

    • man zshmisc перечислены все доступные последовательности под заголовком SIMPLE PROMPT ESCAPES.

Ответ 4

Если вы ссылаетесь на .zshrc в каталоге dotfiles и хотите ссылаться на другие файлы в каталоге, попробуйте следующее:

SOURCE=${(%):-%N}
while [ -h "$SOURCE" ]; do
  DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
  SOURCE="$(readlink "$SOURCE")"
  [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"
done
DOTFILES_DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"

(Я получил цикл script от здесь.)

Ответ 5

Возможно, вы ищете $_?

# foo.sh
source foo2.sh

и

# foo2.sh
echo $_

дает

# ./foo.sh
foo2.sh