Bash脚本与java的类路径问题

Bash脚本与java的类路径问题

内容/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/ 是使程序作用于目录而不是符号链接的一种方法。”

相关内容