6

EDITED

The question was more about bash script them java environment and thanks for those whom had the patience and spare the time to reply me. I am much obliged.

As for the Java environment I started using sdkman. When I started this little script I was actually looking for something just like that, I was considering doing something similar. Whoever is looking for an answer to my question I recommend using the tool. It doesn't matter if you get yourself your own script, I urge you to git it a try.

The sdkman will care for language version installation, side lunges need (like maven, gradle and kotlin) as well as environment variables.

https://sdkman.io/


Original Question

I'm building a bash script to set both the JAVA_HOME and the PATH of the user automatically considering the version of the active java, however for some reason PATH is not being built correctly, it is adding blanks instead of ": ", could anyone tell me why?

Below the script.

Thanks!

#!/bin/bash

export JAVA_HOME=$(dirname $(dirname `readlink -f /etc/alternatives/java`))

IFS=':';
for i in $PATH;
do
        JAVA1=$i/bin/java
        JAVA2=$i/java
        if [ -d "$i" ];
        then
                if [ ! -L "$JAVA1" ] && [ -x "$JAVA1" ] || [ ! -L "$JAVA2" ] && [ -x "$JAVA2" ];
                then
                        echo "dropping path: $i";
                else
                        NEW=$NEW:$i
                fi
        fi
done
PATH=$NEW:$JAVA_HOME/bin
echo 
echo "Final:"
echo $PATH

Sample output:

$ ./java_home_setter.sh 
dropping path: /usr/lib/jvm/java-8-openjdk-amd64/jre/bin

Final:
 /usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin /usr/games /usr/local/games /snap/bin /usr/lib/jvm/java-8-openjdk-amd64/bin

2 Answers 2

5

Thast's because you have altered IFS variable to use ':'

so when its output your variable its replaced with default output field separator which is 'space' thinking that ':' is input field separator .

you have take backup of it before using IFS like below :

OIFS=$IFS
IFS=':';

after 'for' loop is done , restore it :

IFS=$OIFS

Also remove the ':' which starts with no path preceding that

PATH=${PATH#:*}    

Your script should be like :

#!/bin/bash

export JAVA_HOME=$(dirname $(dirname `readlink -f /etc/alternatives/java`))

OIFS=$IFS
IFS=':';
for i in $PATH;
do
        JAVA1=$i/bin/java
        JAVA2=$i/java
        if [ -d "$i" ];
        then
                if [ ! -L "$JAVA1" ] && [ -x "$JAVA1" ] || [ ! -L "$JAVA2" ] && [ -x "$JAVA2" ];
                then
                        echo "dropping path: $i";
                else
                        NEW=$NEW:$i
                fi
        fi
done
IFS=$OIFS
PATH=$NEW:$JAVA_HOME/bin
PATH=${PATH#:*}
echo 
echo "Final:"
echo $PATH
2
  • Adding the first export statement to my .bashrc did the job like a charm. I didnt go for rest since my PATH is auto adjusted by alternatives. It works when my jdk selected is 17 but i dont see any reason why it shouldn't work with other jdk versions.
    – Gautam
    Commented May 6, 2023 at 5:46
  • Still not clear - Why we need dirname twice ? export JAVA_HOME=$(dirname readlink -f /etc/alternatives/java) this should work or ?
    – Gautam
    Commented May 6, 2023 at 6:46
5

Why not set the current java version with:

sudo update-alternatives --config java
sudo update-alternatives --config javac

(and whatever else java binary you need)

Then set the following in your .bashrc or .zshrc:

#!/bin/bash
if [ -z "${JAVA_HOME}" ]
then
    JAVA_HOME=$(readlink -nf $(which java) | xargs dirname | xargs dirname)
    if [ ! -e "$JAVA_HOME" ]
    then
        JAVA_HOME=""
    fi
    export JAVA_HOME=$JAVA_HOME
fi

script source

This is sufficient to have a configured java enviroment, there's no need to set the PATH variable, as it's already managed by the alternatives framework.

Cheers F.

5
  • This evaluates the JAVA_HOME to /usr/lib/jvm which is the topmost folder for all jdk installations and not the precise jdk folder. Am I missing something ?
    – Gautam
    Commented May 6, 2023 at 5:43
  • I'm not sure @Gautam , unfortunately in this moment I don't have a machine to test. What I can tell you is this: OP asked how to swap SDK version by using update-alternatives. As far as I can remember, that tool let you choose a version, and create a symbolic link afterwards. What I don't remember exactly is the purpose of the script, but as you can see, it reads the sym link, then splits it into parts (xargs dirname) and check if the linked path exists. If that's the case, it assigns that path to JAVA_HOME, which is linked to the sdk root (not bin folder!)
    – funder7
    Commented May 8, 2023 at 3:33
  • 1
    I ended up using part of the solution provided in the previous answer which worked like a charm i.e. export JAVA_HOME=$(dirname $(dirname `readlink -f /etc/alternatives/java`))
    – Gautam
    Commented May 8, 2023 at 9:26
  • You should check what the OP suggested, I've read it yesterday in the question...It seems a nice & solution too :-) Cheers
    – funder7
    Commented May 9, 2023 at 1:19
  • I've just tried sdkman, it works very well and it's easy to install/configure.
    – funder7
    Commented Aug 18, 2023 at 11:34

You must log in to answer this question.

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