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

首先看一下Process类:

  1. ProcessBuilder.start() Runtime.exec 方法创建一个本机进程,并返回 Process 子类的一个实例,该实例可用来控制进程并获得相关信息。
    Process 类提供了执行从进程输入、执行输出到进程、等待进程完成、
  2. 检查进程的退出状态以及销毁(杀掉)进程的方法。
  3. 创建进程的方法可能无法针对某些本机平台上的特定进程很好地工作,比如,本机窗口进程,守护进程,Microsoft Windows 上的 Win16/DOS 进程,或者 shell 脚本。创建的子进程没有自己的终端或控制台。它的所有标准 io(即 stdinstdout stderr
  4. 操作都将通过三个流 (getOutputStream()、getInputStream() getErrorStream()) 重定向到父进程。
  5. 父进程使用这些流来提供到子进程的输入和获得从子进程的输出。因为有些本机平台仅针对标准输入和输出流提供有限的缓冲区大小,如果读写子进程的输出流或输入流迅速出现失败,则可能导致子进程阻塞,甚至产生死锁。
  6. 当没有 Process 对象的更多引用时,不是删掉子进程,而是继续异步执行子进程。
  7. 对于带有 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.  
  3. #查询sql
  4. SQL=$1
  5. #查询结果保存文件
  6. RESULT_FILE=$2
  7. #数据库连接
  8. DB_NAME=scott
  9. DB_PWD=tiger
  10. DB_SERVER=DB_TEST
  11.  
  12. RESULT=`sqlplus -S ${DB_NAME}/${DB_PWD}@${DB_SERVER}<< !
  13. set heading off
  14. set echo off
  15. set pages 0
  16. set feed off
  17. set linesize 3000
  18. ${SQL}
  19. /
  20. commit
  21. /
  22. !`
  23.  
  24. echo "${RESULT}" >> ${RESULT_FILE}
  25. 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和内存的消耗很大。

From:

http://blog.csdn.net/a19881029/article/details/8063758

http://www.avajava.com/tutorials/lessons/how-do-i-run-another-application-from-java.html

http://stackoverflow.com/questions/13991007/execute-external-program-in-java

http://stackoverflow.com/questions/15218892/running-a-java-program-from-another-java-program

http://www.rgagnon.com/javadetails/java-0014.html

http://www.javacoffeebreak.com/faq/faq0030.html

http://www.youtube.com/watch?v=AiVpzFH9zRc

Java程序执行Linux命令(JSP运行其他程序)的更多相关文章

  1. Java程序执行Linux命令

    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. 使程序在Linux下后台运行,程序运行前后台切换

    一.为什么要使程序在后台执行 我们计算的程序都是周期很长的,通常要几个小时甚至一个星期.我们用的环境是用putty远程连接到日本Linux服务器.所以使程序在后台跑有以下三个好处: 1:我们这边是否关 ...

  6. Java 执行linux命令(转)

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

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

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

  8. node.js服务端程序在Linux上持久运行

    如果要想在服务端部署node.js程序,让其持久化运行,就不能单单使用npm start命令运行,当然了,这样运行是毫无问题的,但是当关闭xshell窗口或者是关闭进程的时候(其实关闭xshell窗口 ...

  9. 设置PATH 环境变量、pyw格式、命令行运行python程序与多重剪贴板

    pyw格式简介: 与py类似,我认为他们俩卫衣的不同就是前者运行时候不显示终端窗口,后者显示 命令行运行python程序: 在我学习python的过程中我通常使用IDLE来运行程序,这一步骤太过繁琐( ...

随机推荐

  1. iOS-更新CocoaPods出现错误 提示重复文件

    当多人开发的时候,或者引入了一些别人的第三方库文件的时候,当我们再更新CocoaPods时会出现错误,错误提示有一些文件 出现重复,这个时候我们需要查看一些是什么文件出现了重复,错误提示是xxxx三方 ...

  2. Oracle Instant Client的安装和使用

    转自:https://www.cnblogs.com/chinalantian/archive/2011/09/09/2172145.html 根据自己需求到Oracle网站(http://www.o ...

  3. Office word中去掉首页的页眉

    1.首先将光标位置移动到第二页的开始,然后点击页面布局命令. 2.页面布局里面找到分隔符,找到下一页的分隔符.(分页符分页) 3.双击第二页的页眉,打开页眉编辑菜单.将连接到前一条页眉的命令去掉. 4 ...

  4. dev grid 常用方法

    绑定数据源 public void Data(){DataTable td = new DataTable();DataRow row = td.NewRow();foreach (GridColum ...

  5. Qt隐式共享与显式共享

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/Amnes1a/article/details/69945878Qt中的很多C++类都使用了隐式数据共 ...

  6. Kubernetes网络框架

    // cmd/kubelet/app/server.go -1.func UnsecuredKubeletDeps(s *options.KubeletServer) (*kubelet.Kubele ...

  7. kubestack 源码分析

    简介:KubeStack is an OpenStack network provider for kubernetes.KubeStack is devided into two functions ...

  8. mysql 中sum (if()) 用法

    原表: id    fenlei     time 1      分类1      20130316 2      分类2      20130316 3      分类3      20130317 ...

  9. 小木虫emuch遭封禁,新域名muchong.com尚可用

    各位虫友: 因为小木虫站点个别虫子违反论坛规定,擅自上传了政治擦边的违规资源.导致小木虫域名 emuch.net 被通信局封禁! 我们第一时间对违规资源进行了删除处理,接下来.我们也将大批量的对站内的 ...

  10. HDU1712:ACboy needs your help(分组背包)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1712 解释看这里:http://www.cnblogs.com/zhangmingcheng/p/3940 ...