正常来说java调用shell命令就是用

  1. String[] cmdAry = new String[]{"/bin/bash","-c",cmd}
  1. Runtime.getRuntime().exec(cmdAry);

实际上就是创建个子进程去执行这个命令。

问题来了: 如果我执行下面这句命令

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

这种输出日志量特别大的命令,就会出现卡死,一直不动,后来了解到 子进程产生的输出日志都会写到窗口里,因为窗口有缓存大小限制,

到达一定程度时就会卡死,导致死锁,后来百度了其他作者的资料才发现,这种直接调用exec用法是不好的,数据量小可能体现不出来,

数据量大的时候 就会直接缓存爆满 子进程就会卡死,所以我们可以创建2个线程来消费子进程运行shell命令产生的日志,正确用法如下

  1. public class TestController {
  2.  
  3. @GetMapping("/exp")
  4. public void addHomePage(String cmd) throws InterruptedException, IOException {
  5. //创建子进程调用shell命令
  6. new MyThread(cmd).start();
  7. }
  8. }
  9.  
  10. class MyThread extends Thread {
  11. String cmd;
  12. MyThread(String cmd)
  13. {
  14. this.cmd = cmd;
  15. }

  16. public void run(){
  17. Process proc = null;
  18. try {
           String[] cmdAry = new String[]{"/bin/bash","-c",cmd}
  19. proc = Runtime.getRuntime().exec(cmdAry);
  20. } catch (IOException e) {
  21. e.printStackTrace();
  22. }
  23. //接收子进程的汇报信息和错误信息,避免阻塞
  24. new StreamGobbler(proc.getInputStream(),"INFO").start();
  25. new StreamGobbler(proc.getErrorStream(),"ERROR").start();
  26.  
  27. //获取子进程执行结果状态
  28. int status= 0;
  29. try {
  30. status = proc.waitFor();
  31. } catch (InterruptedException e) {
  32. e.printStackTrace();
  33. }
  34. if (status == 0){
  35. System.out.println("执行完毕");
  36. }else
  37. System.out.println("执行失败");
  38.  
  39. //销毁子进程
  40. proc.destroy();
  41. }
  42. }
  43.  
  44. class StreamGobbler extends Thread
  45. {
  46. InputStream is;
  47. String type;
  48.  
  49. StreamGobbler(InputStream is, String type)
  50. {
  51. this.is = is;
  52. this.type = type;
  53. }
  54.  
  55. public void run()
  56. {
  57. try
  58. {
  59. InputStreamReader isr = new InputStreamReader(is);
  60. BufferedReader br = new BufferedReader(isr);
  61. String line=null;
  62. while ( (line = br.readLine()) != null)
  63. System.out.println(type + ">" + line);
  64. } catch (IOException ioe)
  65. {
  66. ioe.printStackTrace();
  67. }
  68. }
  69. }

这样就可以了  记得以后调用shell命令都用这种形式

java 执行shell命令遇到的坑的更多相关文章

  1. java 执行shell命令及日志收集避坑指南

    有时候我们需要调用系统命令执行一些东西,可能是为了方便,也可能是没有办法必须要调用.涉及执行系统命令的东西,则就不能做跨平台了,这和java语言的初衷是相背的. 废话不多说,java如何执行shell ...

  2. Android Java执行Shell命令

    最新内容建议直接访问原文:http://www.trinea.cn/android/android-java-execute-shell-commands/ 主要介绍Android或Java应用中如何 ...

  3. java执行Shell命令

    java程序中要执行linux命令主要依赖2个类:Process和Runtime首先看一下Process类:ProcessBuilder.start() 和 Runtime.exec 方法创建一个本机 ...

  4. [Java] Java执行Shell命令

    Methods ProcessBuilder.start() 和 Runtime.exec() 方法都被用来创建一个操作系统进程(执行命令行操作),并返回 Process 子类的一个实例,该实例可用来 ...

  5. java 执行shell命令

    Runtime.getRuntime().exec http://blog.csdn.net/heyetina/article/details/6555746

  6. 第3节 sqoop:7、通过java代码远程连接linux执行shell命令

    数据库的数据同步软件sqoop 数据同步 关系型数据库到大数据平台 任务:sqoop 是批量导入数据太慢,如何做到实时的数据同步 实时的数据同步工具: canal 阿里开源的一个数据库数据实时同步的软 ...

  7. Android 用java语言执行Shell命令

    最近项目中需要用到java语言来执行shell命令,在网上查了资料, 把自己在项目里用到的命令整理成了工具类开放给大家,希望对大家有用.功能不全,后期我会慢慢添加整合. public class Sh ...

  8. Java 实现 ssh命令 登录主机执行shell命令

    Java 实现 ssh命令 登录主机执行shell命令 1.SSH命令 SSH 为 Secure Shell 的缩写,由 IETF 的网络小组(Network Working Group)所制定:SS ...

  9. 【Hadoop离线基础总结】通过Java代码执行Shell命令

    通过Java代码执行Shell命令 需求 在实际工作中,总会有些时候需要我们通过java代码通过远程连接去linux服务器上面执行一些shell命令,包括一些集群的状态管理,执行任务,集群的可视化界面 ...

随机推荐

  1. 微信小程序入门教程之四:API 使用

    今天是这个系列教程的最后一篇. 上一篇教程介绍了,小程序页面如何使用 JavaScript 脚本.有了脚本以后,就可以调用微信提供的各种能力(即微信 API),从而做出千变万化的页面.本篇就介绍怎么使 ...

  2. rsync实时备份监控命令(详细大全)

    目录 一:rsync介绍 1.rsync简介 2.rsync特性 3.rsync应用场景 4.rsync的传输方式 5.Rsync传输模式 二:RSYNC使用参数 三:参数使用案例 一:rsync介绍 ...

  3. backup archivelog all not backed up

    backup archivelog all not backed up;这条命令可以用来备份没有备份过的归档日志,同时不会备份已经备份过的归档日志.下面是具体用法.第一次备份归档日志 RMAN> ...

  4. Mac OS Fusion Linux虚拟机网络设置

    1.设定网络为nat 2.ifconfig查看mac机的ip 3.进入虚拟机设定网络,手动指定自己ip为mac机网段ip,xxx.xxx.xxx.2是固定的路由及DNS的ip 4.关闭再打开网络即可访 ...

  5. SqlServer基础语法

    历史 有很多软件公司开发了数据库产品,其中微软公司的数据库产品命名为 SQL Server,也称 MS SQL Server. 1989年 Ashton-Tate/Microsoft SQL Serv ...

  6. jdk1.5新特性之------->可变参数

    /* jdk1.5新特性之------->可变参数 需求: 定义一个函数做加法功能(函数做几个数据 的加法功能是不确定). 可变参数的格式: 数据类型... 变量名 可变参数要 注意的细节: 1 ...

  7. linux_17

    nginx负载均衡中常见的算法及原理有哪些? 用rewrite规则实现将所有到a域名的访问rewrite到b域名 实现反向代理客户端IP透传 利用LNMP实现wordpress站点搭建

  8. 统计学习:逻辑回归与交叉熵损失(Pytorch实现)

    1. Logistic 分布和对率回归 监督学习的模型可以是概率模型或非概率模型,由条件概率分布\(P(Y|\bm{X})\)或决 策函数(decision function)\(Y=f(\bm{X} ...

  9. js reduce累加器

    ​ reduce 是es6 新增的数组操作方法 意为累加器 使用方法如下 [1,1,1,1].reduce((total,currentValue,index)=>{ },initialValu ...

  10. 神奇小证明之——世界上只有5个正多面体+构造x3=2a3

    今天我彻底放飞自我了...作业还没写完...但就是要总结一些好玩的小性质...谁给我的勇气呢?