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
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 ofPS4
. Here, we makePS4
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 thebash
start-up files will not mess with.bash -xlic ""
This starts bash with the options
-x
, which causes all commands to be displayed with thePS4
prompt,-l
which instructsbash
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.
-
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?– nohupOct 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.– John1024Oct 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?– nohupOct 24, 2015 at 18:30 -
1Processes 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.– John1024Oct 25, 2015 at 4:32