JAVA调用Shell脚本--及阻塞的解决办法

用java调用shell,使用

Process p=Runtime.getRuntime().exec(String[] cmd);

Runtime.exec方法将产生一个本地的进程,并返回一个Process子类的实例,该实例可用于控制进程或取得进程的相关信息。

由于调用Runtime.exec方法所创建的子进程没有自己的终端或控制台,因此该子进程的标准IO(如stdin,stdou,stderr)都通过

p.getOutputStream(),

p.getInputStream(),

p.getErrorStream()

方法重定向给它的父进程了.用户需要用这些stream来向 子进程输入数据或获取子进程的输出。

例如:Runtime.getRuntime().exec("ls")

另外需要关心的是Runtime.getRuntime().exec()中产生停滞(阻塞,blocking)的问题?

这个是因为Runtime.getRuntime().exec()要自己去处理stdout和stderr的输出,

就是说,执行的结果不知道是现有错误输出(stderr),还是现有标准输出(stdout)。

你无法判断到底那个先输出,所以可能无法读取输出,而一直阻塞。

例如:你先处理标准输出(stdout),但是处理的结果是先有错误输出(stderr),

一直在等错误输出(stderr)被取走了,才到标准输出(stdout),这样就产生了阻塞。

解决办法:

用两个线程将标准输出(stdout)和错误输出(stderr)。

参考代码:

import java.util.*;

import java.io.*;

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();

}

}

}

public class ExecRunner

{

public static void main(String args[])

{

if (args.length < 1)

{

System.out.println("USAGE: java GoodWindowsExec ");

System.exit(1);

}

try

{

String osName = System.getProperty("os.name" );

String[] cmd = new String[3];

if( osName.equals( "Windows NT" ) )

{

cmd[0] = "cmd.exe" ;

cmd[1] = "/C" ;

cmd[2] = args[0];

}

else if( osName.equals( "Windows 95" ) )

{

cmd[0] = "command.com" ;

cmd[1] = "/C" ;

cmd[2] = args[0];

} else {

StringTokenizer st = new StringTokenizer(command, " ");

cmd = new String[st.countTokens()];

int token = 0;

while (st.hasMoreTokens()) {

String tokenString = st.nextToken();

// System.out.println(tokenString);

cmd[token++] = tokenString;

}

}

Runtime rt = Runtime.getRuntime();

System.out.println("Execing " + cmd[0] + " " + cmd[1]

+ " " + cmd[2]);

Process proc = rt.exec(cmd);

// any error message?

StreamGobbler errorGobbler = new

StreamGobbler(proc.getErrorStream(), "ERROR");

// any output?

StreamGobbler outputGobbler = new

StreamGobbler(proc.getInputStream(), "OUTPUT");

// kick them off

errorGobbler.start();

outputGobbler.start();

// any error???

int exitVal = proc.waitFor();

System.out.println("ExitValue: " + exitVal);

} catch (Throwable t)

{

t.printStackTrace();

}

}

}

参考文章:

When Runtime.exec() won't

Navigate yourself around pitfalls related to the Runtime.exec() method

http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=4

java无阻塞执行脚本,JAVA调用Shell脚本-及阻塞的解决方法相关推荐

  1. java channelexec_java-使用SSH exec通道调用Shell脚本,但忽略对其他Shell脚本的调用

    我正在使用此处提供的有用示例,使用JSch exec在远程服务器上执行Shell脚本.我可以看到脚本返回的回显,并且结尾处的退出状态为0-乍一看,一切看起来都很不错. 但是,问题在于脚本本身会调出其他 ...

  2. hive运行mysql脚本_用java代码调用shell脚本执行sqoop将hive表中数据导出到mysql

    1:创建shell脚本 1 touch sqoop_options.sh2 chmod 777 sqoop_options.sh 编辑文件  特地将执行map的个数设置为变量  测试 可以java代码 ...

  3. java调用shell脚本_Java 执行Shell脚本指令

    一.介绍 有时候我们在Linux中运行Java程序时,需要调用一些Shell命令和脚本.而Runtime.getRuntime().exec()方法给我们提供了这个功能,而且Runtime.getRu ...

  4. Java 调用Shell脚本执行 SCP命令提示Authorized users only. All activity may be monitored and reported.

    近期做了个小项目主要是关于数据处理这方面的. 在Java后端调用服务器上Shell脚本,而Shell脚本执行时一条Scp执行结果的提示报 Authorized users only. All acti ...

  5. java执行shell命令权限不够_Java调用shell脚本解决传参和权限问题的方法|chu

    1. java 执行shell java 通过 Runtime.getRuntime().exec() 方法执行 shell 的命令或 脚本,exec()方法的参数可以是脚本的路径也可以是直接的 sh ...

  6. java调用shell脚本并传递参数

    最近业务上需要java调用执行shell脚本进行一些业务处理,写了个demo,记录下. 主要代码 @RequestMapping("/copy/database")@Respons ...

  7. java调用shell脚本及注意事项

    需求: get方法下载远程zip包,然后zip包解压,取出第一级目录再次进行压缩获取新的压缩zip包. 问题: 如果选择使用java代码的IO流操作,在不确定zip包大小的情况下可能会占用很大的内存, ...

  8. [转载]JAVA调用Shell脚本

    FROM:http://blog.csdn.net/jj12345jj198999/article/details/11891701 在实际项目中,JAVA有时候需要调用C写出来的东西,除了JNI以外 ...

  9. java调用shell脚本,解决传参和权限问题

    1. java 执行shell java 通过 Runtime.getRuntime().exec() 方法执行 shell 的命令或 脚本,exec()方法的参数可以是脚本的路径也可以是直接的 sh ...

最新文章

  1. 二进制安装mysql集群_基于二进制安装Cloudera Manager集群
  2. 今年阿里双十一CDN要冲历史之最,峰值带宽达到5000G+,来高手分析一下他们的CDN节点数量和规模...
  3. python单行动态刷新不了_python 解决tqdm模块不能单行显示的问题
  4. SQL_delete删除数据
  5. 阿里巴巴Java开发文档2020版学习-代码格式
  6. Pygame实现”走四棋儿“双人对战小游戏
  7. 局域网桌面共享软件(优化版)
  8. 利用SolidWorks解决方案取得健身器材市场的领先地位!
  9. 【操作篇】Excel中如何快速插入空白行,小白技巧
  10. EasyNVR对接EasyCloud视频云平台进行云端录像
  11. python输入两个数求和笔试题_Python练习题1.1从键盘输入两个数,求它们的和并输出...
  12. 从会种田到“慧种田”,传感技术成“刚需”!
  13. Win7 64位静态过PG,文件修改记录,备忘
  14. 短视频的地方搞笑配音怎么做?分享一个小技巧,不会方言也能配
  15. 牛客网入门题--最大公约数与最小公倍数
  16. InvalidDefinitionException: No serializer found for class... 因为没有给对象写get、set方法
  17. 来自一位搞算法的本科生的学习感想
  18. 下载视频-you-get
  19. SpringBoot+Thymeleaf模板实现中英文页面文字翻译
  20. 云端(Cloud)多租户网络技术

热门文章

  1. 【死磕JVM】五年 该知道JVM加载机制了!
  2. 当打开淘宝的那一刻,它就知道你想要的是什么
  3. 《我想进大厂》之Spring夺命连环10问
  4. 今生不再见, VS Code !
  5. 2019年这50个Kafka面试题,你知道答案么?
  6. Hadoop对Spark:正面比拼报告(架构、性能、成本、安全性和机器学习)
  7. 一年管理成富翁,三年市场路路通,十年技术一场空
  8. 服务器设备监控系统,服务器设备监控系统
  9. 关于中台的思考与尝试
  10. 平衡树性质与基本算法