2
\$\begingroup\$

I'm writing a bash script to manage multiple JDKs, the script is very simple, you have to choose a directory when you store all the jdk's, and the script maintain a symlink to the current jdk'. TheJAVA_HOMEis always pointing to thesymlink`.

In order to use the script you have to source the jdk-manager.bash in .bash_profile or .profile

The script is used by calling jdk function from the command line.


Questions:

  • is there any security issues in the script ?
  • is there any way to implement the same functionality without sourcing the shell file in a dotfile ?

#! /usr/bin/env bash

#set -u
#set -e

#to modify
JDK_ROOT="$HOME/local" # change it to the directory that contain the jdk's

JDK_PATTERN="[0-9]\.[0-9]\.+([0-9])?(_+([0-9]))"
CURRENT_JDK="$JDK_ROOT/.current_jdk"
SESSION=0;

# colors 
textred=$(tput setaf 1)
texttyellow=$(tput setaf 3)
textreset=$(tput sgr0)
textgreen=$(tput setaf 2)

########################################################################""
# functions 
########################################################################"

# ascii art
_print_java_ascii() {
printf ${texttyellow}"
   _     _ _                                                     
  (_) __| | | __     _ __ ___   __ _ _ __   __ _  __ _  ___ _ __ 
  | |/ _  | |/ /____|  _   _ \ / _  |  _ \ / _  |/ _  |/ _ \  __|
  | | (_| |   <_____| | | | | | (_| | | | | (_| | (_| |  __/ |   
 _/ |\__ _|_|\_\    |_| |_| |_|\__ _|_| |_|\__ _|\__  |\___|_|   
|__/                                             |___/           

"${textreset}                                                     
}

_is_jdk() {
  return `[[ "$1" == jdk${JDK_PATTERN} ]]`
}


# init the current symlink
_init_current() {
  if [[ ! -L $CURRENT_JDK ]];
  then
    ln -s /dev/null $CURRENT_JDK
  fi
}

_get_current_jdk() {
  basename `readlink -f $CURRENT_JDK`
}
# list all available jdks in the JDK_ROOT directory
_ls_jdks() {
  for file in $(ls $JDK_ROOT)
  do
    if `_is_jdk "$file"`
     then
      if [[ $file == `_get_current_jdk` ]]
       then
    printf "${textgreen} > $file\n"
      else
    printf "${textreset}   $file\n"
      fi
    fi
  done
}

_set_current_jdk() {
  jdk="jdk$1"
  if `_is_jdk $jdk` && [[ -d "$JDK_ROOT/$jdk" ]]
  then
    rm "$CURRENT_JDK"
    ln -sf "$JDK_ROOT/$jdk" "$CURRENT_JDK"
    printf "${textgreen} INFO: ${textreset}Updating the \$JAVA_HOME to $JDK_ROOT/${textgreen}`_get_current_jdk`${textreset}  .\n\n";
    _ls_jdks;
  else
    printf "${textred} ERROR: ${textreset} there is no $jdk in $JDK_ROOT \n"
  fi
}

########################################################################""
# main
########################################################################"

export JAVA_HOME=$CURRENT_JDK;
export PATH="$JAVA_HOME/bin:$PATH"

jdk() {
 if [[ $SESSION -eq 0 ]]
  then
  _print_java_ascii;
  SESSION=1;
fi

_init_current;

if [[ $# -eq 0 ]]
then
  _ls_jdks;
else
  _set_current_jdk $1
fi
}
\$\endgroup\$
1
\$\begingroup\$

Let's see:

  • There's no need to use return in the last statement of a function. By default, the return code of the last command is returned anyway.
  • Using backticks for evaluation is deprecated - you should use $(command args) instead. It is also more readable.
  • Use More Quotes™. The current script does not handle even whitespace in file names, much less newlines or - at the beginning.
  • Indent consistently, otherwise it's difficult to follow the code.
  • Are you sure you need to initialize the symlink?
  • Don't parse ls output.
| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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