Изменить:
В вашем скрипте добавьте следующую строку:
shopt -s extdebug
, затем вы можете получить имя файла источника и номер строки в этом файле, с которого начинается определение функции:
def=($(declare -F function_1))
echo "function name: ${def[0]}"
echo "line number: ${def[1]}"
echo "file name: ${def[@]:2}" # the array slice makes it work even if the filename contains spaces
Оригинальный ответ:
Вам не нужно знать во время выполнения, какой файл предоставляет функцию. Возможно, если вы разместите свой код, мы сможем лучше понять, что вам нужно.
Когда вы исходите из файла (например, с помощью ". foo.inc
"), он как будто находится в основном файле.
Если вам по какой-то причине нужно знать, загружен ли он еще, вы можете сделать что-то уродливое (сродни тому, как дети в машине плачут «мы уже здесь?» Каждые несколько секунд):
function_check ()
{
local fn found notfound;
for fn in $function_list;
do
if [[ -n $(declare -F $fn) ]]; then
found+=$fn" ";
else
notfound+=$fn" ";
fi;
done;
echo $found;
function_list=$notfound
}
function_list="function_1 function_2 function_3"
. foo.inc
foo_list=$(function_check)
. bar.inc
bar_list=$(function_check)
. baz.inc
baz_list=$(function_check)
echo "Warning: the following functions were not found: $function_list"
Функция function_check
проверяет наличие функций, перечисленных в $function_list
, и, если они найдены, повторяет их и удаляет их из списка. (Скажи так быстро три раза!)
Редактировать
Вот способ сделать то, что я думаю, может быть очень близко к тому, что вы хотите:
В каждой ваших функций добавьте тест для опции, которая возвращает свой источник, например:
function_1 ()
{
if [[ $1 == "--source" ]]
then
echo "source: ${BASH_SOURCE}"
return
fi
# do your function stuff
}
Затем в вашем скрипте вы можете найти файлы, содержащие функции, и найти источник конкретной функции:
function_1 --source
отобразит имя файла, из которого оно получено. И, конечно, вы можете действовать на это:
if [[ $(function_1 --source) == /some/dir/file ]]
then
do_something
fi