3

I need to find at least a file where $JAVA_HOME is defined (exported). Is there any smart way to do that besides text search in files?

1 Answer 1

9

To find which file defines JAVA_HOME, run:

PS4='+ $BASH_SOURCE:$LINENO:' BASH_XTRACEFD=7 bash -xlic ""  7>trace.out

This generate debug output for a bash login shell and saves it to the file trace.out. There will be many lines in that file. The lines look like:

+ /etc/profile:7:PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
+ /etc/profile:9:export PATH

This shows (a) the name of the file currently being executed, (b) the line number, and (c) debug output for that line in that file. Just search through that for JAVA_HOME. For example:

grep JAVA_HOME trace.out

How it works

  • PS4='+ $BASH_SOURCE:$LINENO:'

    When creating an execution trace, bash will prepend every line with an expansion of PS4. Here, we make PS4 display the source file and line number that is being read.

  • BASH_XTRACEFD=7

    This sends the execution trace to 7 which is a file descriptor chosen in hopes that it is one that the bash start-up files will not mess with.

  • bash -xlic ""

    This starts bash with the options -x, which causes all commands to be displayed with the PS4 prompt, -l which instructs bash to treat this like a login shell, -i which makes the shell interactive, and -c "" which makes the new shell exit once initialization is complete.

  • 7>trace.out

    This redirects the trace output to file.

4
  • Nice explanation. Could you kindly clarify, why to use -l which instructs bash to treat this like a login shell and -i which makes the shell interactive? And while using the fd as 7, could it be possible for a random process to have already been using an fd by the same number?
    – nohup
    Oct 22, 2015 at 6:52
  • 1
    @nohup (1) Without the -i and -l options, bash would skip some of its startup files. We want bash to read all of them so that we can find which one is causing the problems. (2) Because each process tree gets its own fd 7, it wouldn't matter is some random process was using it. It would only matter if one of the bash startup files was using it. That is a risk but typically not a big one.
    – John1024
    Oct 24, 2015 at 5:00
  • Very well @John1024. Thank you for your kind explanation on the fd part. I have a doubt. I checked the pids of the current shell with each bash -i and bash -l and it changes and a new process is spawned each time. ~ echo $$ 13760 ~ bash -i ~ echo $$ 13786 ~ exit logout ~ echo $$ 13760 ~ bash -l ~ echo $$ 13807 ~ exit logout If each process gets its own fd 7, the bash startup files using it would interfere with our oneliner? Also is there a good documentation for understanding the fd part?
    – nohup
    Oct 24, 2015 at 18:30
  • 1
    Processes inherit their creator's file descriptors. A process can change its file descriptors and those changes are passed on to its children but not to its parent. In the conceivable but unlikely event that a bash startup file modified fd 7, then it would interfere. If some "random" process modifies fd 7, it has no affect on us.
    – John1024
    Oct 25, 2015 at 4:32

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .