Изменение переменных окружения

Вообще-то shell-скрипт не может менять переменные окружения. Точнее может, но только для себя и порожденных им процессов. В данном же случае хочется поменять переменные окружения родительского bash процесса, который вызвал наш скрипт. Это невозможно. Выход в том, что наш "скрипт" должен выполняться в том же bash процессе, что его "вызывает". Делается это так: "source /home/gelin/bin/javahome". Или даже так: ". /home/gelin/bin/javahome".

Этот скрипт изменяет переменные окружения JAVA_HOME и PATH для переключения между различными Java Development Kit (JDK). JDK расположены в различных каталогах файловой системы. "Разрешенные" к использованию JDK перечислены в отдельном файле. Проверяется наличие выбираемого JDK в списке, наличие соответсвующего каталога, в переменной PATH соответствующий путь заменяется на новый.

Файл /home/gelin/bin/javahome:

# This is not ordinary shell script!!!
# Because it tryes to change environment variables, it must be run in current shell, not in subshell.
# Use ". javahome" or define alias for this.
#
# (c) 2005-2006 Denis Nelubin aka Gelin
#
# This script replaces current values of JAVA_HOME and PATH environment variable
# for switch between different Java SDK implementations.
# This script uses list of JDK for check previous PATH state.

JDK_LIST="/home/gelin/etc/jdk.list"

JDK=$1

if [ -$JDK- == -- ]
then
    # print usage
    echo Usage: . javahome \<JDK name\>
    echo JDKs listed in $JDK_LIST are:
    while read JDK_PATH
    do
    echo `basename $JDK_PATH`
    done < $JDK_LIST
else

    # define search flags
    HAVE_IN_LIST=false
    HAVE_PATH=false

    # for each listed jdk
    while read JDK_PATH
    do
    # find path by base name (last part of path)
    if [ -`basename $JDK_PATH`- == -$JDK- ]
    then
        HAVE_IN_LIST=true
        NEW_PATH=$JDK_PATH
    fi
    # find currently selected (in PATH) JDK
    if [ ${PATH/$JDK_PATH/} != $PATH ]  #when removing, PATH changed
    then
        HAVE_PATH=true
        OLD_PATH=$JDK_PATH
    fi
    # warning if list is incorrect
    if [ ! -d $JDK_PATH ]
    then
        echo Warning: $JDK_PATH is not exist
    fi
    done < $JDK_LIST

    # specified JDK is not listed
    if [ -$HAVE_IN_LIST- != -true- ]
    then
    echo $JDK is not listed in $JDK_LIST  Can\'t change environment.
    fi

    # JDK is not listed in PATH
    if [ -$HAVE_PATH- != -true- ]
    then
    echo $NEW_PATH/bin is not in current PATH
    if [ -$HAVE_IN_LIST- == -true- ]
    then
        echo Inserting $NEW_PATH/bin to PATH ...
        PATH=$NEW_PATH/bin:"${PATH}"
        JAVA_HOME=$NEW_PATH
    fi
    fi

    # found in PATH and in list
    if [ -$HAVE_IN_LIST- == -true- -a -$HAVE_PATH- == -true- ]
    then
        JAVA_HOME=$NEW_PATH
        PATH=${PATH/$OLD_PATH/$NEW_PATH}
    fi

    # update environment
    export JAVA_HOME
    export PATH

    # print result
    echo JAVA_HOME=$JAVA_HOME
    echo PATH=$PATH

fi

Список JDK. Файл /home/gelin/etc/jdk.list:

/usr/lib/jvm/java-gcj
/opt/jdk5

Чтобы не писать каждый раз точку и полный путь к скрипту, определим алиас. Тогда "скрипт" действительно будет работать почти как настоящий скрипт:

gelin@asus:~$ tail -1 /home/gelin/.bashrc
alias javahome='. /home/gelin/bin/javahome'