java 执行shell命令遇到的坑
正常来说java调用shell命令就是用
String[] cmdAry = new String[]{"/bin/bash","-c",cmd}
Runtime.getRuntime().exec(cmdAry);
实际上就是创建个子进程去执行这个命令。
问题来了: 如果我执行下面这句命令
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 {
String[] cmdAry = new String[]{"/bin/bash","-c",cmd}
proc = Runtime.getRuntime().exec(cmdAry);
} 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命令遇到的坑的更多相关文章
- java 执行shell命令及日志收集避坑指南
有时候我们需要调用系统命令执行一些东西,可能是为了方便,也可能是没有办法必须要调用.涉及执行系统命令的东西,则就不能做跨平台了,这和java语言的初衷是相背的. 废话不多说,java如何执行shell ...
- Android Java执行Shell命令
最新内容建议直接访问原文:http://www.trinea.cn/android/android-java-execute-shell-commands/ 主要介绍Android或Java应用中如何 ...
- java执行Shell命令
java程序中要执行linux命令主要依赖2个类:Process和Runtime首先看一下Process类:ProcessBuilder.start() 和 Runtime.exec 方法创建一个本机 ...
- [Java] Java执行Shell命令
Methods ProcessBuilder.start() 和 Runtime.exec() 方法都被用来创建一个操作系统进程(执行命令行操作),并返回 Process 子类的一个实例,该实例可用来 ...
- java 执行shell命令
Runtime.getRuntime().exec http://blog.csdn.net/heyetina/article/details/6555746
- 第3节 sqoop:7、通过java代码远程连接linux执行shell命令
数据库的数据同步软件sqoop 数据同步 关系型数据库到大数据平台 任务:sqoop 是批量导入数据太慢,如何做到实时的数据同步 实时的数据同步工具: canal 阿里开源的一个数据库数据实时同步的软 ...
- Android 用java语言执行Shell命令
最近项目中需要用到java语言来执行shell命令,在网上查了资料, 把自己在项目里用到的命令整理成了工具类开放给大家,希望对大家有用.功能不全,后期我会慢慢添加整合. public class Sh ...
- Java 实现 ssh命令 登录主机执行shell命令
Java 实现 ssh命令 登录主机执行shell命令 1.SSH命令 SSH 为 Secure Shell 的缩写,由 IETF 的网络小组(Network Working Group)所制定:SS ...
- 【Hadoop离线基础总结】通过Java代码执行Shell命令
通过Java代码执行Shell命令 需求 在实际工作中,总会有些时候需要我们通过java代码通过远程连接去linux服务器上面执行一些shell命令,包括一些集群的状态管理,执行任务,集群的可视化界面 ...
随机推荐
- Tomcat-Tomcat服务器实例使用的其他细节说明
1,修改工程访问路径 context修改路径 ,访问的地址也会改变成一致 2,修改运行的端口号 3,修改运行时使用的浏览器 4,配置资源热部署
- CTFSHOW-SSRF篇
之前就想着写一下 ctfshow 的 wp, 但由于时间问题,一直没有机会, 其实是懒≥.≤ 这次趁着寒假刷几篇ctfshow的文章 那,开始吧. web351 存在一个flag.php页面,访问会返 ...
- 在js中如何区分深拷贝与浅拷贝?
一.自我理解 简单来讲就是:深拷贝层层拷贝,浅拷贝只拷贝第一层. 在深拷贝中,新对象中的更改不会影响原对象,而在浅拷贝中,新对象中的更改,原对象中也会跟着改. 在深拷贝中,原对象与新对象不共享相同的属 ...
- ORA-15081: failed to submit an I/O operation to a disk
Problem: While restoring controlfile to test environment, from filesystem or tape environment after ...
- php include,require,include_once,require_once 的区别
include(),require(),include_once(),require_once()作用都是包含并运行指定文件,但是使用场景又有很大区别. 1.include()和require()的区 ...
- webpack4 mini-css-extract-plugin
在使用webpack的extract-text-webpack-plugin插件提取单独打包css文件时,报错,说是这个插件要依赖webpack3的版本. webpack4得使用mini-css-ex ...
- term&match得区别 text&keyword区别
Text 概念 Text 数据类型被用来索引长文本,比如说电子邮件的主体部分或者一款产品的介绍.这些文本会被分析,在建立索引前会将这些文本进行分词,转化为词的组合,建立索引.允许 ES来检索这些词语. ...
- mybatis的一对多(collection)
使用图解: 低效率查询: 高效率查询: 1 查询用联合查询 2<collection 里面不写column
- shell脚本批量配置多台主机静态ip
关于脚本 服务器使用之前,都需要先配置静态IP,那就将这种简单重复的工作,交给脚本来处理吧,让我们运维有更多的时间喝茶看报刷微博 脚本使用 sh ssh.sh ip.txt ssh.sh 为脚本的名称 ...
- shell脚本的“奇迹暖暖“之行 -- printf彩色输出
printf \n" \n代表换行 "\e[1;30m \e[0m" 深灰 "\e[1;31m \e[0m" 红色 "\e[1;32m \e ...