内容/opt/scripts/jvm/jvm.script.sh
#!/bin/bash
JAVA_HOME='/java'
PATH="$PATH:/$JAVA_HOME/bin"
java -cp ./classes:./lib com.mystuff.bar.foo.myclass &
内容/etc/init.d/init.script.sh
home='/opt/scripts/jvm'
program=jvm.script.sh
su scriptuser -c "$home/$program"
/opt/scripts/jvm
符号链接到/data/shellscripts
(意味着/data/shellscripts
作为真实目录存在)。
运行 init 脚本失败,cannot find class com.mystuff.bar.foo.myclass
但如果我 su 到同一用户并运行它,它就可以工作,为什么?
当我运行时,su scriptuser -c 'declare -p JAVA_HOME'
我得到JAVA_HOME not found
,但是如果我先向用户苏(使用su scriptuser
)并运行它,我得到JAVA_HOME="/java"
这可能听起来很疯狂,但如果我在初始化脚本中的 home 变量中添加一个尾部斜杠,它似乎可以解决问题。
所以:
home='/opt/scripts/jvm'
变成
home='/opt/scripts/jvm/'
看起来环境因素正在扰乱符号链接的处理方式。
答案1
这是一个关于路径和su'ing的令人困惑的问题。当您运行此命令时:
$java -cp ./classes:./lib com.mystuff.bar.foo.myclass
并得到“找不到类”,这意味着java无法在./classes或./lib中找到该类。如果你要么
a) 使用绝对路径,或 b) 在运行命令之前 cd 到正确的位置 (su scriptuser -c "cd $home ; ./$program")
它会工作得更可靠。
至于为什么在 home 后面加一个“/”会有不同,这看起来确实很奇怪。您可以分解 strace/truss 并查看该命令正在执行哪些系统调用。这个答案引用了 posix 规范:
linux如何处理多个路径分隔符(/home////用户名///文件)
并表示“对于作用于目录条目的程序,如果 foo 是目录的符号链接,则传递 foo/ 是使程序作用于目录而不是符号链接的一种方法。”