1. 程式人生 > >Java for linux Runtime 執行需要轉義的指令碼(shell)

Java for linux Runtime 執行需要轉義的指令碼(shell)

最近寫了一個利用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過載方法。