Nick Bull
Nick Bull

Reputation: 9876

Get bash function path from name

A hitchhiker, waned by the time a function is taking to complete, wishes to find where a function is located, so that he can observe the function for himself by editting the file location. He does not wish to print the function body to the shell, simply get the path of the script file containing the function. Our hitchhiker only knows the name of his function, which is answer_life.

Imagine he has a function within a file universal-questions.sh, defined like this, the path of which is not known to our hitchhiker:

function answer_life() {
    sleep $(date --date='7500000 years' +%s)

    echo "42"
}

Another script, called hitchhiker-helper-scripts.sh, is defined below. It has the function above source'd within it (the hitchhiker doesn't understand source either, I guess. Just play ball.):

source "/usr/bin/universal-questions.sh"

function find_life_answer_script() {
    # Print the path of the script containing `answer_life`
    somecommand "answer_life" # Should output the path of the script containing the function.
}

So this, my intrepid scripter, is where you come in. Can you replace the comment with code in find_life_answer_script that allows our hitchhiker to find where the function is located?

Upvotes: 3

Views: 195

Answers (2)

oakymax
oakymax

Reputation: 1474

Your hitchhiker can also try to find the answer this way:

script=$(readlink -f "$0")

sources=$(grep -oP 'source\s+\K[\w\/\.]+' $script)

for s in "${sources[@]}"
do
  matches=$(grep 'function\s+answer_life' $s)
  if [ -n "${matches[0]}" ]; then
    echo "$s: Nothing is here ("
  else
    echo "$s: Congrats! Here is your answer!"
  fi
done

This is for case if debug mode will be unavailable on some planet )

Upvotes: 1

bishop
bishop

Reputation: 39494

In bash operating in extended debug mode, declare -F will give you the function name, line number, and path (as sourced):

function find_life_answer_script() {
    ( shopt -s extdebug; declare -F answer_life )
}

Like:

$ find_life_answer_script
answer_life 3 ./universal-questions.sh

Running a sub-shell lets you set extdebug mode without affecting any prior settings.

Upvotes: 4

Related Questions