Java程序执行Linux命令
Java程序中要执行linux命令主要依赖2个类:Process和Runtime
首先看一下Process类:
- ProcessBuilder.start() 和 Runtime.exec 方法创建一个本机进程,并返回 Process 子类的一个实例,
- 该实例可用来控制进程并获得相关信息。Process 类提供了执行从进程输入、执行输出到进程、等待进程完成、
- 检查进程的退出状态以及销毁(杀掉)进程的方法。
- 创建进程的方法可能无法针对某些本机平台上的特定进程很好地工作,比如,本机窗口进程,守护进程,Microsoft Windows
- 上的 Win16/DOS 进程,或者 shell 脚本。创建的子进程没有自己的终端或控制台。它的所有标准 io(即 stdin、stdout 和 stderr)
- 操作都将通过三个流 (getOutputStream()、getInputStream() 和 getErrorStream()) 重定向到父进程。
- 父进程使用这些流来提供到子进程的输入和获得从子进程的输出。因为有些本机平台仅针对标准输入和输出流提供有限的缓冲区大小,
- 如果读写子进程的输出流或输入流迅速出现失败,则可能导致子进程阻塞,甚至产生死锁。
- 当没有 Process 对象的更多引用时,不是删掉子进程,而是继续异步执行子进程。
- 对于带有 Process 对象的 Java 进程,没有必要异步或并发执行由 Process 对象表示的进程。
特别需要注意的是:
1,创建的子进程没有自己的终端控制台,所有标注操作都会通过三个流
(getOutputStream()、getInputStream() 和 getErrorStream()) 重定向到父进程(父进程可通过这些流判断子进程的执行情况)
2,因为有些本机平台仅针对标准输入和输出流提供有限的缓冲区大小,如果读写子进程的输出流或输入流迅速出现失败,
则可能导致子进程阻塞,甚至产生死锁
- abstract void destroy()
- 杀掉子进程。
- abstract int exitValue()
- 返回子进程的出口值。根据惯例,值0表示正常终止。
- abstract InputStream getErrorStream()
- 获取子进程的错误流。
- abstract InputStream getInputStream()
- 获取子进程的输入流。
- abstract OutputStream getOutputStream()
- 获取子进程的输出流。
- abstract int waitFor()
- 导致当前线程等待,如有必要,一直要等到由该 Process 对象表示的进程已经终止。
- 如果已终止该子进程,此方法立即返回。如果没有终止该子进程,调用的线程将被阻塞,直到退出子进程。
特别需要注意:如果子进程中的输入流,输出流或错误流中的内容比较多,最好使用缓存(注意上面的情况2)
再来看一下Runtime类:
- 每个Java应用程序都有一个Runtime类实例,使应用程序能够与其运行的环境相连接。可以通过getRuntime方法获取当前运行时环境。
- 应用程序不能创建自己的Runtime类实例。
介绍几个主要方法:
- Process exec(String command)
- 在单独的进程中执行指定的字符串命令。
- Process exec(String command, String[] envp)
- 在指定环境的单独进程中执行指定的字符串命令。
- Process exec(String command, String[] envp, File dir)
- 在有指定环境和工作目录的独立进程中执行指定的字符串命令。
- Process exec(String[] cmdarray)
- 在单独的进程中执行指定命令和变量。
- Process exec(String[] cmdarray, String[] envp)
- 在指定环境的独立进程中执行指定命令和变量。
- Process exec(String[] cmdarray, String[] envp, File dir)
- 在指定环境和工作目录的独立进程中执行指定的命令和变量。
command:一条指定的系统命令。
envp:环境变量字符串数组,其中每个环境变量的设置格式为name=value;如果子进程应该继承当前进程的环境,则该参数为null。
dir:子进程的工作目录;如果子进程应该继承当前进程的工作目录,则该参数为null。
cmdarray:包含所调用命令及其参数的数组。
以下为示例(要打成可执行jar包扔到linux下执行):
- public class test {
- public static void main(String[] args){
- InputStream in = null;
- try {
- Process pro = Runtime.getRuntime().exec(new String[]{"sh",
- "/home/test/test.sh","select admin from M_ADMIN",
- "/home/test/result.txt"});
- pro.waitFor();
- in = pro.getInputStream();
- BufferedReader read = new BufferedReader(new InputStreamReader(in));
- String result = read.readLine();
- System.out.println("INFO:"+result);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
在这用的是Process exec(String[] cmdarray)这个方法
/home/test/test.sh脚本如下:
- #!/bin/sh
- #查询sql
- SQL=$1
- #查询结果保存文件
- RESULT_FILE=$2
- #数据库连接
- DB_NAME=scott
- DB_PWD=tiger
- DB_SERVER=DB_TEST
- RESULT=`sqlplus -S ${DB_NAME}/${DB_PWD}@${DB_SERVER}<< !
- set heading off
- set echo off
- set pages 0
- set feed off
- set linesize 3000
- ${SQL}
- /
- commit
- /
- !`
- echo "${RESULT}" >> ${RESULT_FILE}
- echo 0;
特别需要注意的是,当需要执行的linux命令带有管道符时(例如:ps -ef|grep java),用上面的方法是不行的,解决方式是将需要执行的命令作为参数传给shell
- public class Test {
- public static void main(String[] args) throws Exception{
- String[] cmds = {"/bin/sh","-c","ps -ef|grep java"};
- Process pro = Runtime.getRuntime().exec(cmds);
- pro.waitFor();
- InputStream in = pro.getInputStream();
- BufferedReader read = new BufferedReader(new InputStreamReader(in));
- String line = null;
- while((line = read.readLine())!=null){
- System.out.println(line);
- }
- }
- }
PS:
Runtime.getRuntime().exec()这种调用方式在java虚拟机中是十分消耗资源的,即使命令可以很快的执行完毕,频繁的调用时创建进程消耗十分客观。
java虚拟机执行这个命令的过程是,首先克隆一条和当前虚拟机拥有一样环境变量的进程,再用这个新的进程执行外部命令,最后退出这个进程。频繁的创建对CPU和内存的消耗很大
原文地址:http://blog.csdn.net/a19881029/article/details/8063758
Java程序执行Linux命令的更多相关文章
- Java程序执行Linux命令(JSP运行其他程序)
java程序中要执行linux命令主要依赖2个类:Process和Runtime 首先看一下Process类: ProcessBuilder.start() 和 Runtime.exec 方法创建一个 ...
- 使用java代码执行linux命令
前提: java代码是在windows下面写的,要打包放到linux下面运行,并且执行某个脚本. java代码: try { // 起作用的代码其实就下面这一行, 参数是linux中要执行的代码 Ru ...
- android 程序执行linux命令注意事项
一:问题描述 在已经root过的android设备下,app执行一个linux命令,app需要获取su权限,在某些android主板下会出现异常, Command: [su] Working D ...
- 通过java代码执行Linux命令查询声卡和显卡 型号
package test; import java.io.BufferedReader; import java.io.InputStreamReader; public class ExcuteLi ...
- Java程序执行cmd命令
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.i ...
- Java 执行linux命令(转)
转自 http://blog.csdn.net/a19881029/article/details/8063758 java程序中要执行linux命令主要依赖2个类:Process和Runtime 首 ...
- 利用java实现可远程执行linux命令的小工具
在linux的脚本中,如果不对机器做其他的处理,不能实现在linux的机器上执行命令.为了解决这个问题,写了个小工具来解决这个问题. 后面的代码是利用java实现的可远程执行linux命令的小工具,代 ...
- paip.注册java程序为LINUX系统服务的总结。
paip.注册java程序为LINUX系统服务的总结. ////////////////实现开机启动. 标准方法是按照/etc/init.d/下面的文件,修改一下:然后chkconfig xxx on ...
- 性能监控之Java程序执行解析
大家好,最近接触javassist技术,研究过程中对Java程序执行过程进行了一系列探索,弄清楚了几个盲区(仅针对个人而言),现将经验与大家分享. 1.编码->.java 通常指写代码的过程,最 ...
随机推荐
- 解决的方法:warning: Clock skew detected. Your build may be incomplete.
因为时钟同步问题.出现 warning: Clock skew detected. Your build may be incomplete.这种警告, 解决的方法: find . -type f ...
- C#核编之内建数据类型
这个随笔中的重点之一是说明:C#中所提供的关键字都是相应系统类型的简化符号(如int是System.Int32类型的简化符号) 一.内建数据类型与层级结构 所有的C#内建数据类型都支持默认的构造函数, ...
- DOM事件对象
触发DOM上的事件时会产生一个事件对象event. event的内容:与事件有关的信息,导致事件的元素,事件的类型及其他与特定事件相关的信息. event对象会传入到事件处理程序中. 一.DOM 中的 ...
- java调用Command命令
----------- import java.io.BufferedReader; import java.io.InputStreamReader; /** * 此类用来执行Command命令 * ...
- Oracle GoldenGate配置异构数据库数据传输(oracle到sqlserer)的dml操作(带pump进程)
实验环境:os01:Red Hat Enterprise Linux Server release 5.1 (32位)db01:oracle 10.2.0.1.0 os02:Windows 7 (32 ...
- Oracle使用imp/exop远程导入导出dmp数据
在导入导出数据之前,习惯性的检查一下,看看我们自己的机器可不可以连接远程的Oracle主机,检测方法是tnsping SERVICE_NAME.我的机器如下: C:\Users\zx>tnspi ...
- 【MVC】过滤器
APS.NET MVC中(以下简称“MVC”)的每一个请求,都会分配给相应的控制器和对应的行为方法去处理,而在这些处理的前前后后如果想再加一些额外的逻辑处理.这时候就用到了过滤器. MVC支持的过滤器 ...
- 2013ACM-ICPC亚洲区南京站现场赛G题
题目大意:一个n维的系统中随机选一个向量(X1,X2,X3,...,Xn),其中0<=Xi<=R,且X1^2+X2^2+X3^2+……+Xn^2 <= R^2. 现在给定n,R.求X ...
- JS判断是否在微信浏览器打开
if (browser.versions.mobile) {//判断是否是移动设备打开.browser代码在下面 var ua = navigator.userAgent.toLowerCase(); ...
- codeforces 702E Analysis of Pathes in Functional Graph 倍增
题目链接 给一个图, 然后给出每条边的权值和一个k值. 让你求出从每个点出发, 走k次能获得的边权的和以及边权的最小值. 用倍增的思想, 求出每个点走一次能到达的点, 权值和以及最小值, 走两次..四 ...