Назад | Перейти на главную страницу

Странное поведение, которое в скрипте оболочки запущено как разветвленный процесс

Итак, у меня есть Java-процесс, который выполняет некоторую автоматизацию. Одна из вещей, которую он должен сделать, - это найти JDK на случайных машинах.

Поэтому я написал сценарий оболочки, чтобы попытаться найти дом JDK, предполагая, что javac находится на пути.

При локальном тестировании этого сценария оболочки я обнаружил довольно странное поведение, которое мне хотелось бы понять.

Странное поведение сводится к which команда вела себя довольно странно. Фрагмент сценария, который я не могу объяснить, начинается с

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

(Я добавил javac -version и which javac || echo "rv=$?" просто чтобы проверить, что у меня есть действительный PATH в разветвленном процессе)

Если я использую 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... все работает

Итак, я нашел решение этого ...

Так что в основном то, как мой 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`"

Потом все заработало

Запись этого для потомков, поскольку потребовалось время, чтобы отследить основную причину моей собственной глупости (что было по уважительной причине в другом месте кода)