Странное поведение, которое в сценарии оболочки запускается как разветвленный процесс
Так что у меня есть 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
... все работает
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`"
Потом все заработало
Запись этого для потомков, поскольку потребовалось некоторое время, чтобы отследить коренную причину моей собственной глупости (что было хорошей причиной в другом месте кода)