今天寫一個用到編譯的程序,遇到了問題。
- 在調用runtime.exec("javac HelloWorld.java");運行完美,也就是有生成.class。
- 而到了runtime.exec("java HelloWorld >> output.txt");卻怎么也無法重定向輸出,連output.txt文件也生成不了。
- 測試"echo hello >> 1.txt" 也是不可以,甚是頭疼,於是乎翻閱資料,這才發現了
- 一個認識上的誤區,就是exec(str)中 不能把str完全看作命令行執行的command。尤其是str中不可包含重定向 ' < ' ' > ' 和管道符' | ' 。
- 那么,遇到這樣的指令怎么辦呢?我們接着往下看:
兩種方法:
我們先看一下官方doc[>link<]給我們提供的重載方法:
- 1. public Process exec(String command) throws IOExecption
- 2. public Process exec(String command,String [] envp) throws IOExecption
- 3. public Process exec(String command,String [] envp,File dir) throws IOExecption
- 4. public Process exec(String[] cmdarray) throws IOExecption
- 5. public Process exec(String[] cmdarray,String [] envp) throws IOExecption
- 6. public Process exec(String[] cmdarray,String [] envp,File dir) throws IOExecption
翻閱其文檔,發現其重載方法4.exec(String []cmdarray) 最簡便適合我們,官方說4.exec() 與執行6.exec(cmdarray,null,null) 效果是一樣的。那么5.exec.(cmdarray,null)也是一樣的咯?
- 於是乎,我們可以這樣寫:
runtime.exec( new String[]{"/bin/bash", "-c", "java HelloWorld >> output.txt"} );
runtime.exec( new String[]{"/bin/bash", "-c", "java HelloWorld >> output.txt"} ,null );
runtime.exec( new String[]{"/bin/bash", "-c", "java HelloWorld >> output.txt"} ,null,null );
不過要注意,如果使用java /home/path/HelloWorld 時,' / '會被解析成 " . ",從而報出 “錯誤: 找不到或無法加載主類 .home.path.HelloWorld ”.
所以,無法使用全路徑的時候,我們需要更改一下策略,把 路徑 改到工作目錄dir 中去,比如:
File dir = new File("/home/path/");
然后用其第6種重載方法,把dir作為第三個參數傳入即可:
String []cmdarry ={"/bin/bash", "-c", "java HelloWorld >> output.txt"}
runtime.exec(cmdarry,null.dir);
當然echo , ls 等命令便不受' / '限制了。
*BTW,exec()取得返回值的標准用法詳見:runtime.exec()的左膀右臂http://blog.csdn.net/timo1160139211/article/details/75050886
總結:
- 當命令中包含重定向 ' < ' ' > ' 和管道符' | ' 時,exec(String command)方法便不適用了,需要使用exec(String [] cmdArray) 或者exec(String []cmdarray,String []envp,File dir)來執行。
例如:
- exec("echo hello >> ouput.txt");
- exec("history | grep -i mvn");
應改為:
- exec( new String[]{"/bin/sh","-c","echo hello >> ouput.txt"});
- exec( new String[]{"/bin/bash","-c","history | grep -i mvn"},null);
