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

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类实例。

介绍几个主要方法:

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

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

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

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

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

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

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

特别需要注意的是,当需要执行的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和内存的消耗很大

对于waitfor 可能死锁的问题,请参见

http://yearsaaaa123789.iteye.com/blog/1404865

Java 执行linux命令(转)的更多相关文章

  1. java执行linux命令的工具类

    package com.starfast.common.util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ja ...

  2. java执行linux命令

    package com.gtstar.collector; import java.io.BufferedReader;import java.io.IOException;import java.i ...

  3. ganymedssh2 java执行linux命令

    需要下载ganymed-ssh2-262.jar package ganymed; import java.io.BufferedReader; import java.io.IOException; ...

  4. java 执行linux命令

    原文地址: http://blog.csdn.net/xh16319/article/details/17302947 package scut.cs.cwh; import java.io.Inpu ...

  5. Java程序执行Linux命令

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

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

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

  7. java执行cmd命令和linux命令

    文章出处http://blog.csdn.net/xh16319/article/details/17302947 一:window下执行cmd指定 一:window下执行cmd指定 程序例子: [j ...

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

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

  9. Java调用Linux命令执行

    调用方式 Java调用linux命令执行的方式有两种,一种是直接调用linux命令,一种是将linux命令写到.sh脚本中,然后调用脚本执行. 详细说明 直接调用:使用java中lang包下面的Run ...

随机推荐

  1. 【Windows核心编程】一个使用内存映射文件进行进程间通信的例子

    进程间通信的方式有很多种,其底层原理使用的都是内存映射文件. 本文实现了Windows核心编程第五版475页上的demo,即使用内存映射文件来在进程间通信. 进程1 按钮[Create  mappin ...

  2. bzoj5259: [Cerc2017]区间

    还是很强的一个题 ORZ肉丝哥哥 对于两个相交区间,假如他们两个都是可行的,那么他们的交也可行,不然没可能两边都把它缺的补上 那么对于答案区间,向右找到第一个可行区间右端点覆盖询问区间,就是最优的 考 ...

  3. Codeforces Round #258 (Div. 2) D. Count Good Substrings —— 组合数学

    题目链接:http://codeforces.com/problemset/problem/451/D D. Count Good Substrings time limit per test 2 s ...

  4. 从ffmpeg filter里出来的数据直接送给avcodec_encode_audio2编码,写文件有错。

    http://hi.baidu.com/mingyuejingque/item/78e71aff57ae9ec5a835a2e4 感谢mingyuejingque st = avformat_new_ ...

  5. python cassandra 创建space table并写入和查询数据

    from cassandra.cluster import Cluster cluster = Cluster(["10.178.209.161"]) session = clus ...

  6. 【CQ18高一暑假前挑战赛5】标程

    [A:暴力] #include<bits/stdc++.h> using namespace std; ; int a[maxn],vis[maxn],N,M; int main() { ...

  7. HihoCoder 1488 : 排队接水(莫队+树状数组)

    描述 有n个小朋友需要接水,其中第i个小朋友接水需要ai分钟. 由于水龙头有限,小Hi需要知道如果为第l个到第r个小朋友分配一个水龙头,如何安排他们的接水顺序才能使得他们等待加接水的时间总和最小. 小 ...

  8. 2.对《30个提高Web程序执行效率的好经验》的理解

    摘自:http://www.cnblogs.com/powertoolsteam/archive/2010/07/12/1775933.html 文章中执行代码的消耗时间是怎么计算的,有知道的同学可以 ...

  9. Python学习资源汇总

    Python 简明教程 (入门必看) * 在线浏览: http://woodpecker.org.cn/abyteofpython_cn/chinese/ Python Tutorial 简体中文版 ...

  10. codevs-1203

    1203 判断浮点数是否相等 题目描述 Description 给出两个浮点数,请你判断这两个浮点数是否相等   输入描述 Input Description 输入仅一行,包含两个浮点数   输出描述 ...