Finding the definition of a bash function

41

14

I work in an environment that has a lot of legacy shell script magic lying around. One thing used heavy from the command line are bash functions that get sourced from some file included from some file included from some file ... included in my .bash_profile. Is there a way to get the definition or even better the location of the definition of these functions without tracking them down through 5 levels of includes?

pythonic metaphor

Posted 2010-05-24T18:42:54.587

Reputation: 2 046

Answers

39

To get the function definition:

type -a function_name

Paused until further notice.

Posted 2010-05-24T18:42:54.587

Reputation: 86 075

@iconoclast: Yes. – Paused until further notice. – 2016-01-22T19:35:59.180

If you're ever in Grand Rapids I'll buy you one in person... otherwise we can find some other way... – iconoclast – 2016-01-23T21:05:16.803

whence -f function_name in zsh – dezza – 2017-09-13T13:17:09.810

66

Assuming you have a function named foo the commands below will get the location of the function's definition, that is it will get the name of the file in which the function is defined as well as the line number at which the function is defined within that file.

# 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

In my case the output of these commands is:

foo 32 /source/private/main/developer/cue.pub.sh

HairOfTheDog

Posted 2010-05-24T18:42:54.587

Reputation: 2 102

3Perfect. I just made this into a bash function in my bashrc file. whereisfunc() {shopt -s extdebug;declare -F $1;shopt -u extdebug} – Neil – 2015-02-12T03:49:09.777

5@Neil: That's handy, thanks: let me suggest using a subshell to localize the effect of shopt without changing the current shell's state: whichfunc () ( shopt -s extdebug; declare -F "$1"; ) (note the use of (...) instead of {...}). – mklement0 – 2016-03-07T21:43:44.923

Why those commands don't work from a script? function works correctly – albfan – 2017-10-07T07:35:22.283

1This should be the accepted answer. – dissolved – 2017-12-13T19:00:09.243

11

To see the definition of the function (as opposed to where it came from), use:

declare -f <functionname>

Joshua Goldberg

Posted 2010-05-24T18:42:54.587

Reputation: 286

1but since there's no location given this is an answer to an unasked question—at least unasked here – iconoclast – 2016-01-22T19:29:09.493

I think this one is better than type -a because it doesn't print the annoy locale dependent first line~~ – yuyichao – 2012-03-16T01:50:45.750

6

bash -x will dump what bash is running as it starts up, which should let you trace it more easily. Don't forget to exit the newly-opened shell.

Ignacio Vazquez-Abrams

Posted 2010-05-24T18:42:54.587

Reputation: 100 516

Handy stuff; to capture the trace in a file, use script out.txt bash -x (again, don't forget to exit). – mklement0 – 2016-03-08T02:43:35.580

-2

another way, that I find even simpler lately:

  which <functionname>

(this will also show whether it's an alias or a script, but will not track down the source of an alias)

Joshua Goldberg

Posted 2010-05-24T18:42:54.587

Reputation: 286

2I think this answer is likely to invite downvotes... it doesn't seem to address the question at all, since there's no information on location. – iconoclast – 2016-01-22T19:28:39.350

I've found it useful for the purpose of tracking down the declaration to use this and find out whether it's an alias or function, and to know the syntax with which it was declared. It's true though that only @HairOfTheDog's answer gives the file directly. – Joshua Goldberg – 2016-04-26T19:42:45.147

2I don't think which gives information about aliases on BSD or mac. Also, this question is about functions, and which does not give information about functions. – dbn – 2013-04-08T20:45:30.273

Thanks for that note. I see now that "which" only resolves functions in zsh, not bash. – Joshua Goldberg – 2013-04-09T01:57:53.453