2

Я пытаюсь заставить Oracle Java 7 update 3 работать правильно на Debian 6. Я скачал и настроил файлы в /usr/java/jre1.7.0_03 . Я также установил следующие две строки в конце /etc/bash.bashrc:

export JAVA_HOME=/usr/java/jre1.7.0_03
export PATH=$PATH:$JAVA_HOME/bin

Вход в систему с другими пользователями и root в порядке, Java можно найти:

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)

Однако есть два случая, когда Java не может быть найден, как описано ниже. Обратите внимание, что оба они работали нормально, когда я ранее установил OpenJDK Java 6 через aptitude, но мне нужен Oracle Java 7 по разным причинам.

  1. Самое главное, что я не могу запускать команды как другой пользователь через su , несмотря на то, что PATH показывает, что Java должна присутствовать. Пользователь был создан с adduser 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"
    ...
    

    Как это может быть в PATH но не может быть найдено? Обновление 05/04/2012: объяснил Дэниел, что это неинтерактивная оболочка, поэтому файлы, такие как /etc/profile и /etc/bash.bashrc , не выполняются. Выполнение полной замены этого пользователя и запуск Java работает:

    root@mc:~# su chris
    chris@mc:/root$ java -version
    java version "1.7.0_03"
    ...
    
  2. При запуске я запускаю скрипт, который показывает похожие, но немного другие проблемы. Скрипт находится в /etc/init.d/start-mystuff.sh и вызывает jar:

    #!/bin/bash
    # /etc/init.d/start-mystuff.sh
    java -jar /opt/Mars.jar
    

    Я могу подтвердить, что скрипт запускается при запуске, и код завершения равен 127, что указывает на то, что команда не найдена. Вставка строки для печати / сохранения PATH показывает, что это:

     /sbin:/usr/sbin:/bin:/usr/bin
    

    Эта вторая проблема не так важна, потому что я могу просто указать на исполняемый файл Java в сценарии, но мне все еще интересно!

Я попытался установить полный PATH и JAVA_HOME явно в /etc/environment что не помогло. Я также попытался установить их в /etc/profile который, похоже, тоже не помогает. Я попытался войти и выйти снова после установки PATH в различных местах (дух!).

В любом случае, длинный пост о том, что, вероятно, будет иметь простое однострочное решение :( Любая помощь с этим будет принята с благодарностью, я потратил слишком много времени, пытаясь исправить это сам

мотивация

Первая проблема может показаться неясной, но в моей системе у меня есть пользователи, которым не разрешен доступ по SSH, но я все еще хочу запускать процессы как они. У меня есть куча скриптов, работающих таким образом, и я не хочу менять их все.

3 ответа3

3

Смотрите: обновление-альтернативы

Также: Debian обычно не рекомендует разработчикам полагаться на переменные ENV, вы обнаружили одну причину этого.

Не то, чтобы они были табу, просто они не должны быть всегда доступны.

Примечание. Добавление вашего Java-пути в конце существующего пути означает, что любая другая Java-версия будет сначала найдена и использована.

(т.е. (символическая ссылка) в /usr /bin)

так:

ls -lah /usr/bin/java

говорит:

lrwxrwxrwx 1 root root 22 апреля 22 2011 г. /usr /bin /java -> /etc /alternatives /java

file $(which java)

/usr/bin/java: символическая ссылка на `/etc/alternatives/java '

file /etc/alternatives/java

/etc/alternatives/java: символическая ссылка на `/usr/lib/jvm/java-6-openjdk-i386/jre/bin/java '

** <дополнительная проблема>, а также служит для демонстрации того, почему $(exec в стиле subshell) предпочтительнее, чем "backtick exec mode" или "eval this".

((поскольку `` '' и "" слишком запутаны, по крайней мере, для меня, и не всегда работают должным образом во всех оболочках все время. Исследуйте POSIX в режиме АКА / бин / ш))

</ сторона вопроса> **

man update-alternatives объясняет, почему существует эта альтернативная система ...

то время

update-alternatives --config java 

может помочь

/usr/local/ - это хорошее место для установки пакетов, собранных из исходного кода ...

Есть и другие способы снятия кожи с вашей кошки.

В том числе:

  • рука, перенаправив ссылку /usr /bin /java :)

(хотя следите за обновлениями или установками зависимостей, сбрасывая их ... не лучший выбор, но это работает)

  • установка псевдонима для Java для каждого пользователя [1]

  • Предшествующий $ PATH в пользователях .bashrc

(вы можете получить .bashrc из .bash_profile, если хотите)

  • вызывая конкретные версии полного пути для экземпляра

(самая безопасная ставка, но, вероятно, не практично)

[1] .alias или .bashrc

help alias

(это встроенный Bash)

Наконец, пример хорошего или плохого: взят из моего 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

Надеюсь, что это помогает, а не мешает

Пит

1

Много вопросов за один раз, но:

1. Ты сделаешь

# su chris -c "echo $PATH"

Это заменит переменную $PATH перед выполнением команды, которая даст $PATH для root. Пытаться

# su chris -c "echo $HOME"

чтобы понять, что я имею в виду.

Вместо этого вы можете сделать

# su chris -c 'echo $PATH'

который будет мешать оболочке от раскрытия переменной в первом случае, и вместо этого фактически получит chris 's $PATH . Скорее всего, вы обнаружите, что изменения не проникли к этому пользователю.

Почему не тогда? /bin/sh связан с /bin/dash в системах Debian, а не с /bin/bash . Dash не будет читать /etc/bash.bashrc . Возможно, вы получили Dash в качестве оболочки по умолчанию для пользователя chris когда он был создан. Посмотрите в /etc/passwd чтобы увидеть, так ли это.

Возможно, это проясняет и вопрос 2.


ОБНОВЛЕНИЕ: Ах, /etc/bash.bashrc только для интерактивных оболочек. Читайте man bash , раздел "ФАЙЛЫ". Вы не запускаете интерактивную оболочку, когда используете таким образом su .


Обновление 2: этот пример является одним из способов:

# su chris -c 'myvar="hi there"; echo $myvar'
hi there

или аналогично:

# su chris -c 'export myvar="hi there"; echo $myvar; export | grep myvar'
hi there
declare -x myvar="hi there"

(при export переменная также доступна для порожденных подпроцессов).

0

Ты можешь использовать

sudo -u <user> -i 

который будет читать .bashrc / .bash_profile .

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .