在作为分叉进程启动的 shell 脚本中出现奇怪的行为

在作为分叉进程启动的 shell 脚本中出现奇怪的行为

所以我有一个 Java 进程正在执行一些自动化操作。它必须执行的一件事是在随机机器上找到 JDK 主目录。

因此我编写了一个 shell 脚本来尝试找到 JDK 主目录(假设它javac位于路径上)。

在本地测试这个 shell 脚本时,我遇到了一些相当奇怪的行为,我想了解一下。

这种奇怪的行为归根结底是因为which命令的行为相当奇怪。我无法解释的脚本片段以以下内容开头:

#/bin/sh
...
if [ -z "$JAVA_HOME" ]; then
    javac -version
    which javac || echo "rv=$?"
    javaExecutable="`which javac`"
    ...

(我添加了javac -versionwhich 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`"

然后一切开始发挥作用

记录这一点以供后人参考,因为花了一段时间才将根本原因追溯到我自己的愚蠢行为(这在代码的其他地方是有充分理由的)

相关内容