Trouble setting up PATH for Java on Debian
Solution 1
See: update-alternatives
Also: Debian generally discourages developers relying on ENV variables, you have discovered one reason why.
Its not that they are taboo its just that they should not be expected to always be available.
Note: Adding your java path at the end of the existing path means that any other java will be found, and used, first.
(i.e. the (symlink) under /usr/bin )
so:
ls -lah /usr/bin/java
says:
lrwxrwxrwx 1 root root 22 Apr 22 2011 /usr/bin/java -> /etc/alternatives/java
file $(which java)
/usr/bin/java: symbolic link to `/etc/alternatives/java'
file /etc/alternatives/java
/etc/alternatives/java: symbolic link to `/usr/lib/jvm/java-6-openjdk-i386/jre/bin/java'
**<side issue> and also serves to demonstrate why $(exec in subshell style) is preferable, to "backtick exec mode" , or " eval this ".
(( as `` '' and "" gets way too confusing, for me at least, and doesn't always work as expected in all shells all of the time. Investigate POSIX mode AKA /bin/sh ))
</side issue>**
man update-alternatives
explains why this alternative system exists ...
meantime
update-alternatives --config java
may help.
/usr/local/ is a good place to install source built packages...
There are also other ways to skin your cat.
Including:
- hand re-pointing the /usr/bin/java link :)
(though watch out for upgrades or dependency installs resetting it.. not a great choice but it works)
setting an alias for java per user [1]
prepending $PATH in the users .bashrc
(you can source .bashrc from .bash_profile if you like)
- calling the specific versions full path per instance
(safest bet but probably not practical)
[1] .alias or .bashrc
help alias
(its a bash builtin)
Finally an example for good or ill: taken from my Debian .bash_profile...
# include .bashrc if it exists
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# set PATH so it includes user's private bin if it exists
if [ -d ~/bin ] ; then
PATH=~/bin:"${PATH}"
fi
Hope this helps rather than hinders
Pete
Solution 2
Many questions in one go, but:
1. You do
# su chris -c "echo $PATH"
This will substitute the variable $PATH
before the command is run, which will give the $PATH
for root. Try
# su chris -c "echo $HOME"
to see what I mean.
Instead, you can do
# su chris -c 'echo $PATH'
which will hinder the shell from expanding the variable in the first case, and instead actually get chris
's $PATH
. You will most likely find that the changes have not permeated to that user.
Why not then? /bin/sh
is linked to /bin/dash
on Debian systems, and not /bin/bash
. Dash won't read /etc/bash.bashrc
. Perhaps you got Dash as default shell for the user chris
when he was created. Look in /etc/passwd
to see if this is the case.
Perhaps this clarifies question 2 as well.
UPDATE: Ah, /etc/bash.bashrc
is only read for interactive shells. Read man bash
, section "FILES". You don't start an interactive shell when you use su
in that way.
Update 2: This example is one way:
# su chris -c 'myvar="hi there"; echo $myvar'
hi there
or similarly:
# su chris -c 'export myvar="hi there"; echo $myvar; export | grep myvar'
hi there
declare -x myvar="hi there"
(with export
, the variable is available to spawned sub-processes as well, as usual).
Related videos on Youtube
milkmansrevenge
Updated on September 18, 2022Comments
-
milkmansrevenge over 1 year
I am trying to get Oracle Java 7 update 3 working correctly on Debian 6. I have downloaded and set up the files in
/usr/java/jre1.7.0_03
. I have also set the following two lines at the end of/etc/bash.bashrc
:export JAVA_HOME=/usr/java/jre1.7.0_03 export PATH=$PATH:$JAVA_HOME/bin
Logging in as other users and root is fine, Java can be found:
chris@mc:~$ java -version java version "1.7.0_03" Java(TM) SE Runtime Environment (build 1.7.0_03-b04) Java HotSpot(TM) 64-Bit Server VM (build 22.1-b02, mixed mode)
However there are two cases where Java cannot be found as detailed below. Note that both of these worked fine when I have previously installed OpenJDK Java 6 via aptitude, but I need Oracle Java 7 for various reasons.
Most importantly, I cannot run commands as another user via
su
, despite the PATH showing that Java should be present. The user was created withadduser chris
root@mc:~# su chris -c "echo $PATH" /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/java/jre1.7.0_03/bin:/bin root@mc:~# su chris -c "java -version" bash: java: command not found root@mc:~# su chris -c "/usr/java/jre1.7.0_03/bin/java -version" java version "1.7.0_03" ...
How can it be in the
PATH
but not be found? Update 05/04/2012: explained by Daniel, to do with it being a non-interactive shell so files such as/etc/profile
and/etc/bash.bashrc
are not executed. Doing a full swap to that user and running Java works:root@mc:~# su chris chris@mc:/root$ java -version java version "1.7.0_03" ...
I run a script on start up which exhibits similar but slightly different problems. The script is located in
/etc/init.d/start-mystuff.sh
and calls a jar:#!/bin/bash # /etc/init.d/start-mystuff.sh java -jar /opt/Mars.jar
I can confirm that the script runs on start up and the exit code is 127, which indicates command not found. Inserting a line to print/save the
PATH
shows that it is:/sbin:/usr/sbin:/bin:/usr/bin
This second problem isn't as important because I can just point directly to the Java executable in the script, but I am still curious!
I have tried setting the full
PATH
andJAVA_HOME
explicitly in/etc/environment
which didn't help. I have also tried setting them in/etc/profile
which doesn't seem to help either. I have tried logging in and out again after settingPATH
in the various locations (duh!).Anyway, long post for what will probably have a simple one line solution :( Any help with this would be greatly appreciated, I have spent far too long trying to fix it by myself.
Motivation
The first problem may seem obscure but in my system I have users that are not allowed SSH access yet I still want to run processes as them. I have a ton of scripts operating in this way and don't want to have to change them all.
-
milkmansrevenge about 12 yearsThanks, I didn't realise it was such a simple substitution when using
"
rather than'
, however:chris:x:1001:1001:,,,:/home/chris:/bin/bash
indicates that/bin/bash
is the default shell forchris
right? -
Daniel Andersson about 12 yearsYes, it does indeed indicate that. However, read the updated section of my answer regarding interactive shells and start up files.
-
Daniel Andersson about 12 years@milkmansrevenge: forgot to highlight your username so you'll get notified, and seem to have missed the edit time with an infinitesimal amount of time... Read my above comment.
-
milkmansrevenge about 12 yearsthanks. I guess my question then simply becomes: How do I set the
$PATH
for non-interactive shells? The "FILES" section forman bash
does hint that my solutions won't work. I'll have a search around for solutions and update my post if I find anything. -
milkmansrevenge about 12 yearsHi Pete, I'll have a play around with update-alternatives; it does seem much better than messing with environment variables. Maybe I should have mentioned in my original post but I started from a minimal install of Debian with no version of Java on it. And I think everyone should be discouraged from relying on env variables, no matter what their system is ;) thanks!
-
milkmansrevenge about 12 yearsYup, it turned out to be ridiculously simple. One line as predicted :)
update-alternatives --install /usr/bin/java jre7u3 /usr/java/jre1.7.0_03/bin/java 5
. I also found another way to solve it using$BASH_ENV
but update-alternatives is the best. I'll update my question so all of this is clear to any other visitors soon. Edit: Can't seem to tag you with@
, guess my rating is too low.