Java程序中要执行linux命令主要依赖2个类:Process和Runtime

首先看一下Process类:

  1. ProcessBuilder.start() 和 Runtime.exec 方法创建一个本机进程,并返回 Process 子类的一个实例,
  2. 该实例可用来控制进程并获得相关信息。Process 类提供了执行从进程输入、执行输出到进程、等待进程完成、
  3. 检查进程的退出状态以及销毁(杀掉)进程的方法。
  4. 创建进程的方法可能无法针对某些本机平台上的特定进程很好地工作,比如,本机窗口进程,守护进程,Microsoft Windows
  5. 上的 Win16/DOS 进程,或者 shell 脚本。创建的子进程没有自己的终端或控制台。它的所有标准 io(即 stdin、stdout 和 stderr)
  6. 操作都将通过三个流 (getOutputStream()、getInputStream() 和 getErrorStream()) 重定向到父进程。
  7. 父进程使用这些流来提供到子进程的输入和获得从子进程的输出。因为有些本机平台仅针对标准输入和输出流提供有限的缓冲区大小,
  8. 如果读写子进程的输出流或输入流迅速出现失败,则可能导致子进程阻塞,甚至产生死锁。
  9. 当没有 Process 对象的更多引用时,不是删掉子进程,而是继续异步执行子进程。
  10. 对于带有 Process 对象的 Java 进程,没有必要异步或并发执行由 Process 对象表示的进程。

特别需要注意的是:

1,创建的子进程没有自己的终端控制台,所有标注操作都会通过三个流

(getOutputStream()、getInputStream() 和 getErrorStream()) 重定向到父进程(父进程可通过这些流判断子进程的执行情况)

2,因为有些本机平台仅针对标准输入和输出流提供有限的缓冲区大小,如果读写子进程的输出流或输入流迅速出现失败,

则可能导致子进程阻塞,甚至产生死锁

  1. abstract  void destroy()
  2. 杀掉子进程。
  3. abstract  int exitValue()
  4. 返回子进程的出口值。根据惯例,值0表示正常终止。
  5. abstract  InputStream getErrorStream()
  6. 获取子进程的错误流。
  7. abstract  InputStream getInputStream()
  8. 获取子进程的输入流。
  9. abstract  OutputStream getOutputStream()
  10. 获取子进程的输出流。
  11. abstract  int waitFor()
  12. 导致当前线程等待,如有必要,一直要等到由该 Process 对象表示的进程已经终止。
  13. 如果已终止该子进程,此方法立即返回。如果没有终止该子进程,调用的线程将被阻塞,直到退出子进程。

特别需要注意:如果子进程中的输入流,输出流或错误流中的内容比较多,最好使用缓存(注意上面的情况2)

再来看一下Runtime类:

  1. 每个Java应用程序都有一个Runtime类实例,使应用程序能够与其运行的环境相连接。可以通过getRuntime方法获取当前运行时环境。
  2. 应用程序不能创建自己的Runtime类实例。

介绍几个主要方法:

  1. Process exec(String command)
  2. 在单独的进程中执行指定的字符串命令。
  3. Process exec(String command, String[] envp)
  4. 在指定环境的单独进程中执行指定的字符串命令。
  5. Process exec(String command, String[] envp, File dir)
  6. 在有指定环境和工作目录的独立进程中执行指定的字符串命令。
  7. Process exec(String[] cmdarray)
  8. 在单独的进程中执行指定命令和变量。
  9. Process exec(String[] cmdarray, String[] envp)
  10. 在指定环境的独立进程中执行指定命令和变量。
  11. Process exec(String[] cmdarray, String[] envp, File dir)
  12. 在指定环境和工作目录的独立进程中执行指定的命令和变量。

command:一条指定的系统命令。

envp:环境变量字符串数组,其中每个环境变量的设置格式为name=value;如果子进程应该继承当前进程的环境,则该参数为null。

dir:子进程的工作目录;如果子进程应该继承当前进程的工作目录,则该参数为null。

cmdarray:包含所调用命令及其参数的数组。

以下为示例(要打成可执行jar包扔到linux下执行):

  1. public class test {
  2. public static void main(String[] args){
  3. InputStream in = null;
  4. try {
  5. Process pro = Runtime.getRuntime().exec(new String[]{"sh",
  6. "/home/test/test.sh","select admin from M_ADMIN",
  7. "/home/test/result.txt"});
  8. pro.waitFor();
  9. in = pro.getInputStream();
  10. BufferedReader read = new BufferedReader(new InputStreamReader(in));
  11. String result = read.readLine();
  12. System.out.println("INFO:"+result);
  13. } catch (Exception e) {
  14. e.printStackTrace();
  15. }
  16. }
  17. }

在这用的是Process exec(String[] cmdarray)这个方法

/home/test/test.sh脚本如下:

  1. #!/bin/sh
  2. #查询sql
  3. SQL=$1
  4. #查询结果保存文件
  5. RESULT_FILE=$2
  6. #数据库连接
  7. DB_NAME=scott
  8. DB_PWD=tiger
  9. DB_SERVER=DB_TEST
  10. RESULT=`sqlplus -S ${DB_NAME}/${DB_PWD}@${DB_SERVER}<< !
  11. set heading off
  12. set echo off
  13. set pages 0
  14. set feed off
  15. set linesize 3000
  16. ${SQL}
  17. /
  18. commit
  19. /
  20. !`
  21. echo "${RESULT}" >> ${RESULT_FILE}
  22. echo 0;

特别需要注意的是,当需要执行的linux命令带有管道符时(例如:ps -ef|grep java),用上面的方法是不行的,解决方式是将需要执行的命令作为参数传给shell

  1. public class Test {
  2. public static void main(String[] args) throws Exception{
  3. String[] cmds = {"/bin/sh","-c","ps -ef|grep java"};
  4. Process pro = Runtime.getRuntime().exec(cmds);
  5. pro.waitFor();
  6. InputStream in = pro.getInputStream();
  7. BufferedReader read = new BufferedReader(new InputStreamReader(in));
  8. String line = null;
  9. while((line = read.readLine())!=null){
  10. System.out.println(line);
  11. }
  12. }
  13. }

PS:

Runtime.getRuntime().exec()这种调用方式在java虚拟机中是十分消耗资源的,即使命令可以很快的执行完毕,频繁的调用时创建进程消耗十分客观。

java虚拟机执行这个命令的过程是,首先克隆一条和当前虚拟机拥有一样环境变量的进程,再用这个新的进程执行外部命令,最后退出这个进程。频繁的创建对CPU和内存的消耗很大

原文地址:http://blog.csdn.net/a19881029/article/details/8063758

Java程序执行Linux命令的更多相关文章

  1. Java程序执行Linux命令(JSP运行其他程序)

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

  2. 使用java代码执行linux命令

    前提: java代码是在windows下面写的,要打包放到linux下面运行,并且执行某个脚本. java代码: try { // 起作用的代码其实就下面这一行, 参数是linux中要执行的代码 Ru ...

  3. android 程序执行linux命令注意事项

    一:问题描述    在已经root过的android设备下,app执行一个linux命令,app需要获取su权限,在某些android主板下会出现异常, Command: [su] Working D ...

  4. 通过java代码执行Linux命令查询声卡和显卡 型号

    package test; import java.io.BufferedReader; import java.io.InputStreamReader; public class ExcuteLi ...

  5. Java程序执行cmd命令

    import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.i ...

  6. Java 执行linux命令(转)

    转自 http://blog.csdn.net/a19881029/article/details/8063758 java程序中要执行linux命令主要依赖2个类:Process和Runtime 首 ...

  7. 利用java实现可远程执行linux命令的小工具

    在linux的脚本中,如果不对机器做其他的处理,不能实现在linux的机器上执行命令.为了解决这个问题,写了个小工具来解决这个问题. 后面的代码是利用java实现的可远程执行linux命令的小工具,代 ...

  8. paip.注册java程序为LINUX系统服务的总结。

    paip.注册java程序为LINUX系统服务的总结. ////////////////实现开机启动. 标准方法是按照/etc/init.d/下面的文件,修改一下:然后chkconfig xxx on ...

  9. 性能监控之Java程序执行解析

    大家好,最近接触javassist技术,研究过程中对Java程序执行过程进行了一系列探索,弄清楚了几个盲区(仅针对个人而言),现将经验与大家分享. 1.编码->.java 通常指写代码的过程,最 ...

随机推荐

  1. Applet 数字签名技术全然攻略

      在这里先对大家说声对不起,毕竟2年前就想写这篇文章,但由于自己太懒惰一直没有写,也是为了给自己留点东西好了,前些日子我老大让我又搞这个东西发现我曾经的资料没留,又凭着自己印象从新来过,但发现网上写 ...

  2. Ubuntu12.04下jamvm1.5.4+classpath-0.98成功执行 helloworld.class

    经过两天的努力,总于在ubuntu以下编译好classpath-0.98与jamvm1.5.4,并能成功的运行类文件:jamvm hellowold,当屏幕上打印出"hello world! ...

  3. 移动端WEB开发 代码片段

    WebApp是指基于Web的系统和应用,其作用是向广大的最终用户发布一组复杂的内容和功能(不明白说的是什么).其实Web APP就是一个针对Iphone.Android等智能手机优化后的web站点,它 ...

  4. mysql插入大量数据

    创建实验表: CREATE TABLE `a` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` char(50)  NOT NULL, `type` ch ...

  5. 【最大流】【HDU3338】【Kakuro Extension】

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3338 题目大意:填数字,使白色区域的值得和等于有值得黑色区域的相对应的值,用网络流来做 题目思路:增加 ...

  6. css绝对定位、相对定位和文档流的那些事

    前言 接触html.和css时间也不短了,但每次用div+css布局的时候心里还是有点儿虚,有时候干脆就直接用table算了,很多时候用div会出现些不可预料的问题,虽然花费一定时间能够解决,但总不是 ...

  7. Qt标题栏图标和运行程序图标设置

    一.标题栏图标 1.*.qrc资源文件中添加图片 2.添加代码 setWindowIcon(QIcon(":/images/paste.png")); //设置窗口上的图标,需要在 ...

  8. vc++ internet

    1.用VC开发ActiveX文档服务器 MFC 4.2不支持开发ActiveX容器,但支持ActiveX服务器.只要在使用MFC AppWizard生成应用程序框架时选择支持Active Docume ...

  9. Javascript获取当前时间戳的方法

    定义日期:   Date 对象用于处理日期和时间.   可以通过 new 关键词来定义 Date 对象.以下代码定义了名为 myDate 的 Date 对象:   var myDate=new Dat ...

  10. SQL Server 数据的创建、增长、收缩

    第一步: create database Studio         on primary          (name = 'Studio',filename='E:\DB\Studio.mdf' ...