Ответ 1
${BASH_SOURCE[0]}
(или, проще говоря, $BASH_SOURCE
[1]) содержит (потенциально относительный) путь содержащего сценария во всех сценариях вызова, особенно также при получении сценария, что неверно для $0
.
Кроме того, как указывает Чарльз Даффи, вызывающий может установить произвольное значение $0
.
С другой стороны, $BASH_SOURCE
может быть пустым, если не $BASH_SOURCE
именованный файл;например:echo 'echo "[$BASH_SOURCE]"' | bash
Следующий пример иллюстрирует это:
Скрипт foo
:
#!/bin/bash
echo "[$0] vs. [${BASH_SOURCE[0]}]"
$ bash ./foo
[./foo] vs. [./foo]
$ ./foo
[./foo] vs. [./foo]
$ . ./foo
[bash] vs. [./foo]
$0
является частью спецификации оболочки POSIX, тогда как BASH_SOURCE
, как следует из названия, зависит от Bash.
[1] Необязательное чтение: ${BASH_SOURCE[0]}
против $BASH_SOURCE
:
Bash позволяет вам ссылаться на элемент 0
переменной массива, используя скалярную запись: вместо записи ${arr[0]}
вы можете написать $arr
; другими словами: если вы ссылаетесь на переменную, как на скаляр, вы получите элемент с индексом 0
.
Использование этой функции скрывает тот факт, что $arr
является массивом, поэтому популярный шелл-код linter shellcheck.net выдает следующее предупреждение (на момент написания статьи):
SC2128: Расширение массива без индекса дает только первый элемент.
Примечание: хотя это предупреждение полезно, оно может быть более точным, поскольку вы не обязательно получите первый элемент: именно элемент с индексом 0
возвращается, поэтому, если первый элемент имеет более высокий индекс - что возможно в Bash - вы получите пустую строку; попробуй 'a[1]='hi'; echo "$a"'
'a[1]='hi'; echo "$a"'
.
(Напротив, zsh
, когда-либо отступник, действительно возвращает первый элемент, независимо от его индекса).
Вы можете отказаться от этой функции из-за ее неясности, но она работает предсказуемо, и, прагматично говоря, вам редко, если вообще понадобится, получить доступ к индексам, отличным от 0
переменной массива ${BASH_SOURCE[@]}
.