Java for linux Runtime 執行需要轉義的指令碼(shell)
阿新 • • 發佈:2019-02-09
最近寫了一個利用java for linux ffmpeg的音訊轉碼服務,發現linux裡能執行的指令碼用java去執行就不行.普通指令碼可以,但是遇到要使用檔名作為引數傳遞(檔名有空格)時就會提示檔案找不到了. 我各種轉義,\" \' \[空格] 全試過了,都不行. 將java拼接出來轉義後的shell字串 命令直接複製到linux shell 終端就能執行. 用java Runtime.exec 就是不行. 後面還是被解決了.
假設有檔名引數/home/123 abc.txt , 那程式就會去讀/home/123,然後提示檔案找不到.
我在shell終端測試發現,只需要給檔名套上引號就好了. 於是我在Java裡面也打算拼接好字串,加好應該加的空格. 結果發現拼出來的命令字串和shell下手動輸入的一模一樣還是執行不了,找不到檔案. 我將java生成打印出的命令複製直接shell執行沒有任何問題! 那麼問題來了. 下面是我犯錯的地方.
原來錯誤重現如下:
1.部分配置檔案:
#ffmpeg path
ffmpeg_path = /home/audiotrans/bin/ffmpeg
#Transcoding parameters #if#:inputFile #of#:outputFile
trans_param_common = -i #if# -ab 256000 -ac 2 -ar 48000 #of#
2.程式碼實現
tips: inputFile 和 outputFile 是兩個檔名(ffmpeg 轉碼用到的輸入檔案,輸出檔案引數) param是獲取配置檔案中的trans_param_common 項
StringBuilder command = new StringBuilder(executePath);
String param = TranscodeConfig.getPropertyInTrans(paramType.toString());
command.append(" ");command.append(param.replace("#if#", "\""+inputFile+"\"").replace("#of#","\""+outputFile+"\""));// 這部分程式碼用\" \' \[空格]都轉義過,執行都提示file not found
Runtime.getRuntime().exec(command.toString()); //省略部分標準輸出,輸入,error流處理程式碼 這裡執行,提示檔案找不到(No such file or directory)
解決實現:
1.部分配置檔案
改了改去 也將 \" \' \[空格]直接放到配置中,也還是不行. 最後改回了原樣,也就是上面的那個配置
2.程式碼實現
String executePath = TranscodeConfig.getPropertyInTrans("ffmpeg_path");
String param = TranscodeConfig.getPropertyInTrans(paramType.toString());
List<String> commands = new ArrayList<String>();
commands.add(executePath);
// split param
String[] params = param.split(" ");
for (String innerParam : params) {
// 如果帶有空格的檔名,直接放進去沒事
if ("#if#".equals(innerParam)) {
innerParam = inputFile;
} else if ("#of#".equals(innerParam)) {
<span style="white-space:pre"> </span>innerParam = outputFile;
}
commands.add(innerParam);
}
<span style="color:#ff0000;">Runtime.getRuntime().exec(commands.toArray(new String[commands.size()])); // 這裡執行的是exec過載方法,arrys:{"程式",引數0,引數1,引數2,引數..]</span>
</pre><pre name="code" class="java">我用這個方法:public Process exec(String[] cmdarray) throws IOException 的時候,空格沒有做任何轉義可以正常執行命令,轉義反而是錯的.
</pre><pre name="code" class="java">到這裡,問題解決了. 其實用java.lang.ProcessBuilder 類 也可以解決這個問題. Runtime底層也是用它實現的. 記錄下,希望能幫助到別的小夥伴!
不要手動轉義,直接用exec過載方法。