首页 > 编程语言 > 详细

java 执行shell命令遇到的坑

时间:2021-06-12 01:03:09      阅读:14      评论:0      收藏:0      [点我收藏+]

正常来说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命令都用这种形式

java 执行shell命令遇到的坑

原文:https://www.cnblogs.com/caiba/p/14875858.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!