Unix
在作為分叉程序啟動的 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 -version
andwhich 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`"
然後一切都開始起作用了
為後代記錄這一點,因為我花了一段時間才將根本原因追溯到我自己的愚蠢(這是程式碼中其他地方的一個很好的理由)