在 Debian 上设置 Java PATH 时出现问题

在 Debian 上设置 Java PATH 时出现问题

我正在尝试让 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,如下所述。请注意,当我之前通过 aptitude 安装了 OpenJDK Java 6 时,这两种情况都运行正常,但由于各种原因,我需要 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:Daniel 解释道,由于它是一个非交互式 shell,因此诸如/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 可执行文件,但我仍然很好奇!

我尝试过在 中设置完整PATHJAVA_HOME明确,/etc/environment但没有帮助。我也尝试过在 中设置它们,/etc/profile但似乎也没有帮助。我尝试过PATH在各个位置设置后再次登录并退出(呃!)。

无论如何,这篇长文可能只有一行简单的解决方案 :( 任何帮助都将不胜感激,我花了太长时间尝试自己解决这个问题。

动机

第一个问题可能看起来不太明显,但在我的系统中,有些用户不允许 SSH 访问,但我仍然想以他们的身份运行进程。我有大量脚本以这种方式运行,我不想全部更改它们。

答案1

参见:更新替代方案

另外:Debian 通常不鼓励开发人员依靠关于 ENV 变量,您发现了一个原因。

这并不是说它们是禁忌,只是我们不应该期望它们总是可用。

注意:在现有路径末尾添加您的 java 路径意味着将首先找到并使用任何其他 java。

(即 /usr/bin 下的(符号链接))

所以:

ls -lah /usr/bin/java

说:

lrwxrwxrwx 1 root root 22 2011 年 4 月 22 日 /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' 的符号链接

**<side issue> 并且还用于说明为什么 $(exec in subshel​​l style) 比“反引号执行模式”或“ eval this ”更可取。

(( 因为 `` '' 和 "" 太令人困惑了,至少对我来说是这样,而且并不总是在所有 shell 中都能按预期工作。调查 POSIX 模式 AKA /bin/sh ))

**

man update-alternatives 解释了为什么存在这个替代系统......

与此同时

update-alternatives --config java 

可能会有帮助。

/usr/local/ 是安装源构建包的好地方......

还有其他方法可以剥猫皮。

包括:

  • 手动重新指向 /usr/bin/java 链接:)

(尽管要注意升级或依赖项安装会重置它..不是一个好的选择但它有效)

  • 为每个用户设置 java 别名 [1]

  • 在用户的 .bashrc 中添加 $PATH

(如果愿意,你可以从 .bash_profile 中获取 .bashrc)

  • 调用每个实例的特定版本完整路径

(最安全的选择但可能不切实际)

[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

希望这能有所帮助而不是阻碍

皮特

答案2

一下子问了很多问题,但是:

1.你做

# su chris -c "echo $PATH"

$PATH这将在命令运行之前替换变量,从而$PATH为 root 提供。尝试

# su chris -c "echo $HOME"

看看我的意思。

相反,你可以这样做

# su chris -c 'echo $PATH'

在第一种情况下,这将阻止 shell 扩展变量,而是实际获取chris$PATH您很可能会发现更改尚未渗透到该用户。

那为什么不呢?在 Debian 系统上/bin/sh链接到,而不是。Dash 不会读取。也许您在创建用户时将 Dash 作为用户的默认 shell 。查看是否是这种情况。/bin/dash/bin/bash/etc/bash.bashrcchris/etc/passwd

这或许也澄清了问题 2。


更新:啊,/etc/bash.bashrc只在交互式 shell 中读取。请阅读,部分“FILES”。以这种方式man bash使用时,您不会启动交互式 shell 。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,变量也可以像往常一样供生成的子进程使用)。

答案3

您可以使用

sudo -u <user> -i 

其内容为.bashrc/ .bash_profile

相关内容