If I have a function like so:

    #!/usr/bin/env bash

    function foo {


and the above function is in .bash_profile, or somewhere.

If I use which foo it won't give me the location of this command in the shell script.

Is there some way for me to discover where it's located or is grep my best bet?

  • The shebang (#!…) is not part of the function, and including it in the question is misleading, given that the function is probably defined in a file that doesn't use a shebang. Nov 27 '17 at 21:49
  • I am just showing to the reader that it's bash, how is that misleading? Nov 27 '17 at 22:38
  • we have two great answers here, so I think people get it Nov 27 '17 at 22:39

This question was already answered here. So there are two things that can be derived from this fact:

  1. You should do a better research before posting your question here (but well, we all are lazy from time to time)
  2. There is a way better trick then grep to do what you want

So you can get a source file and a line number of a shell function in your PATH like this: (credit: this answer)

# Turn on extended shell debugging
shopt -s extdebug

# Dump the function's name, line number and fully qualified source file  
declare -F foo

# Turn off extended shell debugging
shopt -u extdebug
  • Or just use a subshell: (shopt -s extdebug; declare -F foo) to avoid having to restore the option state (and assume it was off beforehand). Nov 27 '17 at 10:00
  • @StéphaneChazelas thanks for the tip! BTW is there a way to make it a script?
    – ddnomad
    Nov 27 '17 at 10:03
  • No, unless you source that script, as declare would have to be run from the shell invocation where that function is defined. You could make it a... function find_func() (shopt -s extdebug; declare -F -- "$@") Nov 27 '17 at 10:10
  • Note that for functions imported from the environment, it would show as foo 0 environment so you would not get back to where the function was defined in the first place. Nov 27 '17 at 10:12

which only searches the path. To see what bash really executes use the built-in command type:

type foo
  • upvoted, this is nice, but it doesn't give me the file and line number, like declare -F foo from the other answer. Nov 27 '17 at 20:09
