1. 程式人生 > 其它 >java 執行shell命令遇到的坑

java 執行shell命令遇到的坑

正常來說java呼叫shell命令就是用

Runtime.getRuntime().exec(cmd);

實際上就是建立個子程序去執行這個命令。

問題來了: 如果我執行下面這句命令

exp system/manager buffer=64000  file=/home/oracle/beifen/beifen.dmp  FULL=Y

這種輸出日誌量特別大的命令,就會出現卡死,一直不動,後來瞭解到 子程序產生的輸出日誌都會寫到窗口裡,因為視窗有快取大小限制,

到達一定程度時就會卡死,導致死鎖,後來百度了其他作者的資料才發現,這種直接呼叫exec用法是不好的,資料量小可能體現不出來,

資料量大的時候 就會直接快取爆滿 子程序就會卡死,所以我們可以建立2個執行緒來消費子程序執行shell命令產生的日誌,正確用法如下

public class TestController {

    @GetMapping("/exp")
    public void addHomePage(String cmd) throws InterruptedException, IOException {
        //建立子程序呼叫shell命令
        new MyThread(cmd).start();
    }
}

class MyThread extends Thread {
    String cmd;
    MyThread(String cmd)
    {
        this.cmd = cmd;
    }
public void run(){ Process proc = null; try { proc = Runtime.getRuntime().exec(cmd); } catch (IOException e) { e.printStackTrace(); } //接收子程序的彙報資訊和錯誤資訊,避免阻塞 new StreamGobbler(proc.getInputStream(),"INFO").start(); new StreamGobbler(proc.getErrorStream(),"ERROR").start();
//獲取子程序執行結果狀態 int status= 0; try { status = proc.waitFor(); } catch (InterruptedException e) { e.printStackTrace(); } if (status == 0){ System.out.println("執行完畢"); }else System.out.println("執行失敗"); //銷燬子程序 proc.destroy(); } } class StreamGobbler extends Thread { InputStream is; String type; StreamGobbler(InputStream is, String type) { this.is = is; this.type = type; } public void run() { try { InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr); String line=null; while ( (line = br.readLine()) != null) System.out.println(type + ">" + line); } catch (IOException ioe) { ioe.printStackTrace(); } } }

這樣就可以了 記得以後呼叫shell命令都用這種形式