我正在尝试让 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。
最重要的是,我无法通过 以其他用户身份运行命令
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" ...
我在启动时运行了一个脚本,它表现出类似但略有不同的问题。该脚本位于并
/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 访问,但我仍然想以他们的身份运行进程。我有大量脚本以这种方式运行,我不想全部更改它们。
答案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 subshell 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.bashrc
chris
/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
。