Це рішення стосується лише bash, а не tcsh. Зауважте, що поширений відповідь ${BASH_SOURCE[0]}
не буде працювати, якщо ви спробуєте знайти шлях із функції.
Я виявив, що цей рядок завжди працює, незалежно від того, чи файл розміщується або працює як сценарій.
echo ${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}
Якщо ви хочете дотримуватися посилання, використовуйте readlink
на шляху, який ви переходите вище, рекурсивно чи не рекурсивно.
Ось сценарій, щоб випробувати його та порівняти його з іншими запропонованими рішеннями. Викликати це як source test1/test2/test_script.sh
або bash test1/test2/test_script.sh
.
#
# Location: test1/test2/test_script.sh
#
echo $0
echo $_
echo ${BASH_SOURCE}
echo ${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}
cur_file="${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}"
cur_dir="$(dirname "${cur_file}")"
source "${cur_dir}/func_def.sh"
function test_within_func_inside {
echo ${BASH_SOURCE}
echo ${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}
}
echo "Testing within function inside"
test_within_func_inside
echo "Testing within function outside"
test_within_func_outside
#
# Location: test1/test2/func_def.sh
#
function test_within_func_outside {
echo ${BASH_SOURCE}
echo ${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}
}
Причина роботи однолінійки пояснюється використанням BASH_SOURCE
змінної середовища та її асоційованого елемента FUNCNAME
.
BASH_SOURCE
Змінна масиву, членами якої є імена файлів джерела, де визначені відповідні імена функцій оболонки в змінній масиву FUNCNAME. Функція оболонки $ {FUNCNAME [$ i]} визначена у файлі $ {BASH_SOURCE [$ i]} і викликана від $ {BASH_SOURCE [$ i + 1]}.
FUNCNAME
Змінна масиву, що містить імена всіх функцій оболонки, що знаходяться в стеці виклику виконання. Елемент з індексом 0 - назва будь-якої функції оболонки, яка виконується в даний час. Найнижчий елемент (той, що має найвищий показник) - "головний". Ця змінна існує лише тоді, коли виконується функція оболонки. Призначення FUNCNAME не мають ефекту і повертають статус помилки. Якщо FUNCNAME не встановлено, він втрачає свої особливі властивості, навіть якщо він згодом скидається.
Цю змінну можна використовувати з BASH_LINENO та BASH_SOURCE. Кожен елемент FUNCNAME має відповідні елементи в BASH_LINENO та BASH_SOURCE для опису стеку викликів. Наприклад, $ {FUNCNAME [$ i]} викликався з файлу $ {BASH_SOURCE [$ i + 1]} за номером рядка $ {BASH_LINENO [$ i]}. Вбудований абонент відображає поточний стек викликів за допомогою цієї інформації.
[Джерело: Посібник Баша]