2011年5月14日 星期六

Java 執行 Runtime.exec() 時, 沒讀取 stdout 可能會造成 deadlock

遇到這問題 google 了一下, 看到 When Runtime.exec() won't 才知道 java.lang.Process 裡有寫:
Because some native platforms only provide limited buffer size for standard input and output streams, failure to promptly write the input stream or read the output stream of the subprocess may cause the subprocess to block, and even deadlock.
沒寫在文件裡, 還真想不到啊。偷懶的解法是執行時將 stdout 和 stderr 導到 /dev/null。注意若想在 exec() 裡重導 IO, 直接執行指令加上重導符號不會有作用。正確的作法如下:
String[] cmd = {"/bin/sh", "-c", "/bin/ls > out.dat"};
Process p = Runtime.getRuntime().exec(cmd);
注意要用 String[] 的方式呼叫 exec, 這樣才能將 "/bin/ls > out.dat" 合在一起傳給 /bin/sh; 用 String 的方式傳一整個字串會出錯, 因為傳單一字串時, Java 會先切開字串再用 String[] 的方式執行它, 而 /bin/ls -c 只接受下一個參數, 不會看到後面的 ">" 和 "out.dat"。

沒有留言:

張貼留言

在 Fedora 下裝 id-utils

Fedora 似乎因為執行檔撞名,而沒有提供 id-utils 的套件 ,但這是使用 gj 的必要套件,只好自己編。從官網抓好 tarball ,解開來編譯 (./configure && make)就是了。 但編譯後會遇到錯誤: ./stdio.h:10...