Как выбирать между "$0"
и"${BASH_SOURCE[0]}"
Это описание из GNU мне не очень помогло.
BASH_SOURCE
An array variable whose members are the source filenames where the
corresponding shell function names in the FUNCNAME array variable are
defined. The shell function ${FUNCNAME[$i]} is defined in the file
${BASH_SOURCE[$i]} and called from ${BASH_SOURCE[$i+1]}
BASH_SOURCE
был добавлен в bash-3.0-alpha. У вас может не быть этого, в зависимости от вашего режима тестирования. Я обнаружил, что он отсутствует как в ранних версиях Solaris, так и в OS X. Также см. Return: может «возвращаться» только из функции или исходного сценария в U & L.SE.Ответы:
Примечание. Для решения, совместимого с POSIX, см. Этот ответ .
${BASH_SOURCE[0]}
(или, проще говоря,$BASH_SOURCE
[1] ) содержит (потенциально относительный) путь содержащего скрипта во всех сценариях вызова, особенно когда скрипт получен из источника , что неверно$0
.Более того, как указывает Чарльз Даффи , вызывающая сторона
$0
может установить произвольное значение.С другой стороны,
$BASH_SOURCE
может быть пустым, если не используется именованный файл; например:echo 'echo "[$BASH_SOURCE]"' | bash
Следующий пример иллюстрирует это:
Сценарий
foo
:$0
является частью спецификации оболочки POSIX, тогда какBASH_SOURCE
, как следует из названия, зависит от Bash.[1] Дополнительное чтение:
${BASH_SOURCE[0]}
vs$BASH_SOURCE
.:Bash позволяет ссылаться на элемент
0
из с массивом переменного , используя скалярное обозначение: вместо написания${arr[0]}
, вы можете написать$arr
; другими словами: если вы ссылаетесь на переменную, как на скаляр , вы получаете элемент по индексу0
.Использование этой функции скрывает тот факт, что
$arr
это массив, поэтому популярный линтер шелл-кода shellcheck.net выдает следующее предупреждение (на момент написания этой статьи):Замечание: хотя это предупреждение полезно, оно может быть более точным, потому что вы не обязательно получите первый элемент:
0
возвращается именно элемент по индексу , поэтому, если первый элемент имеет более высокий индекс, который возможно в Bash - вы получите пустую строку; попробуй'a[1]='hi'; echo "$a"'
.(В отличие от этого
zsh
, когда ренегат, действительно ли возвращать первый элемент, независимо от его индекса).Вы можете выбрать , чтобы отказаться от этой функции из - за своей неизвестности, но это работает предсказуемо и, прагматично говоря, вы будете редко, если когда - либо, необходимость доступа к индексам другой , чем
0
из массива переменных${BASH_SOURCE[@]}
.источник
$BASH_SOURCE
это лучший выбор.Эти сценарии могут помочь проиллюстрировать. Внешний сценарий вызывает средний сценарий, который вызывает внутренний сценарий:
Однако, если мы изменим вызовы сценария на
source
операторы:источник
Для переносимости используйте,
${BASH_SOURCE[0]}
когда он определен, и в$0
противном случае. Это даетПримечательно, что, скажем, в zsh $ 0 действительно содержит правильный путь к файлу, даже если сценарий -
source
d.источник