Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I cannot figure out how to find the file where a bash function is defined (__git_ps1 in my case).

I experimented with declare, type, which, but nothing tells me the source file. I read somewhere that declare can print the file name and the line number, but it was not explained how. The help page for declare does not say it either.

How can I get this information?

share|improve this question
    
If the path to the function's file is not included in $PATH, then type won't work. You might want to try just using find or locate. locate will be much faster, since it uses a pre-existing database, but it won't work if the command was installed just recently. – user628544 Nov 12 at 18:06
    

If you are prepared to run the function, then you can get the information by using set -x to trace the execution and setting the PS4 variable.

  1. Start bash with --debugger or else use shopt -s extdebug to record extra debugging info.

  2. Set PS4, the 'prompt' printed when tracing to show the source line.

  3. Turn on tracing.

  4. you can then run your function and for each line you will get the filename of the function.

  5. use set +x to turn off tracing.

So for this case you would run

bash --debugger
PS4='+ ${BASH_SOURCE[0]} '
set -x ; __git_ps1 ; set +x
share|improve this answer

In general you can't figure out the source file. This is because once the command is loaded into memory there is no reason for the OS to know where it came from. Some commands might print their source files (and may even be truthful about it), either in the course of normal execution or in response to a signal.

__git_ps1 is defined in /usr/share/git/git-prompt.sh and /usr/share/git/completion/git-prompt.sh on my system, Arch Linux, so it may be the same for you.

Have a look at the Invocation section of man bash if you want look for commands specifically sourced at the start of the shell - they may source other files which in turn source other files.

share|improve this answer
    
Can one get a list of files that are sourced upon starting bash? – pfnuesel Nov 12 at 16:41

It doesn't seem to be possible in bash, but it is in zsh:

$ type __git_ps1
> __git_ps1 is a shell function from /usr/share/git/git-prompt.sh
share|improve this answer
    
This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post. - From Review – steve Nov 12 at 17:25
    
The question does specify bash... – Jeff Schaller Nov 12 at 18:19
3  
@JeffSchaller: The obvious way to use this answer is to set up zsh to source the same files that bash would, then use it to find the definition. This answer isn't suggesting switching to zsh, just that it's obviously a useful tool that understands shell syntax better than generic tools like find / locate / grep. – Peter Cordes Nov 12 at 19:28
    
I would claim, then, @PeterCordes , that this answer currently does not do what you say it should do in order to answer the Question. I don't know if zsh natively reads the same files that bash does. – Jeff Schaller Nov 12 at 21:12
    
@JeffSchaller: Agreed this answer is in need of improvement. zsh almost certainly doesn't read the same ~/.whatever files as bash by default, and will only give useful answers for functions defined in shared locations like in this case, that aren't redefined in ~/.bashrc or whatever. – Peter Cordes Nov 12 at 23:22

If you are not willing to run the function, you can still set up debugging and get the information. The steps are

  1. start bash --debugger or shopt -s extdebug before the function is defined.
  2. declare -F __git_ps1

and it will report where the function is defined.

The advantages of this method compared to seeing the annotated execution trace with PS4 are

  • A lot less output
  • It directly answers the question

The advantages of the execution trace are

  • See all called functions at once
  • See the relations between called functions
  • See recursion

I strongly recommend having shopt -s extdebug at the start of both ~/.bashrc and ~/.bash_profile to cover the different files used in different Invocation cases.

share|improve this answer

Declare a function with the same name and set it readonly as early as possible, then activate xtrace mode, something like:

__git_ps1(){ :;}
readonly -f __git_ps1
set -x

After that when you log in you will see trace information that includes sourcing of files. In the moment there is an attempt for a declaration of the existing readonly function, you will see an error message. The last sourced file before it should contain the declaration you look for.

You may need to put this in the system bash profile. Also remember to revert the changes after finding the culprit.

share|improve this answer

Did you try this?

grep -rnw '/path/to/somewhere/' -e "pattern" 

or any of the other commands found here:

http://stackoverflow.com/questions/16956810/how-to-find-all-files-containing-specific-text-on-linux

It seems that I need to give you more of an explanation. Your question asks "" Thus if you run the following command, it should return all files where a bash function is defined.

grep -rnw 'Path2Search' -e "#!/bin/bash"

Bash_Programming

share|improve this answer
1  
Link only answers are absolutely not encouraged. Please add some explanation. – heemayl 2 days ago

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.