所以我有一个 Java 进程正在执行一些自动化操作。它必须执行的一件事是在随机机器上找到 JDK 主目录。
因此我编写了一个 shell 脚本来尝试找到 JDK 主目录(假设它javac
位于路径上)。
在本地测试这个 shell 脚本时,我遇到了一些相当奇怪的行为,我想了解一下。
这种奇怪的行为归根结底是因为which
命令的行为相当奇怪。我无法解释的脚本片段以以下内容开头:
#/bin/sh
...
if [ -z "$JAVA_HOME" ]; then
javac -version
which javac || echo "rv=$?"
javaExecutable="`which javac`"
...
(我添加了javac -version
和which javac || echo "rv=$?"
只是为了检查我在分叉进程中是否有有效的路径)
如果我使用它sh -x
来启动分叉进程,那么我会得到以下输出:
+ '[' -z '' ']'
+ javac -version
javac 1.8.0_11
+ which javac
+ echo rv=1
rv=1
++ which javac
+ javaExecutable=
如果我which
用以下函数替换
_which() {
oldIFS="$IFS"
IFS=':'
for p in $PATH
do
if [ -x "$p/$1" ]; then
echo "$p/$1"
IFS="$oldIFS"
return 0
fi
done
IFS="$oldIFS"
return 1
}
然后一切都按照我期望的方式进行。
如果我直接从命令行调用我的原始脚本……一切正常
如果我通过...调用我的原始脚本ssh localhost sh -x PathToScript
,一切正常
答案1
所以我找到了这个问题的解决方案......
所以基本上我的 Java 进程启动脚本的方式要负部分责任……还有一些其他奇怪的事情。
我的 Java 进程正在清理环境以获得一些“正常”的东西......
Java 代码如下
ProcessBuilder p = new ProcessBuilder(new String[]{
"sh",
"-x",
"pathToScript.sh"
}).redirectErrorStream(
true).redirectOutput(ProcessBuilder.Redirect.INHERIT);
p.environment().clear();
p.start();
所以会发生的情况是,sh
它会在本地建立,PATH
但不会出口。
当我将脚本从
javaExecutable="`which javac`"
要么
export PATH
javaExecutable="`which javac`"
或者
javaExecutable="`PATH="$PATH" which javac`"
然后一切开始发挥作用
记录这一点以供后人参考,因为花了一段时间才将根本原因追溯到我自己的愚蠢行为(这在代码的其他地方是有充分理由的)