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 对象表示的进程。
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 对象表示的进程已经终止。
- 如果已终止该子进程,此方法立即返回。如果没有终止该子进程,调用的线程将被阻塞,直到退出子进程。
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类实例。
每个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)
- 在指定环境和工作目录的独立进程中执行指定的命令和变量。
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();
- }
- }
- }
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;
#!/bin/sh#查询sql
SQL=$1
#查询结果保存文件
RESULT_FILE=$2
#数据库连接
DB_NAME=scott
DB_PWD=tiger
DB_SERVER=DB_TESTRESULT=`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);
- }
- }
- }
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和内存的消耗很大
Java程序执行Linux命令相关推荐
- Java程序执行Linux命令调用EasyPR程序识别车牌号
1)下载解压JDK并配置环境变量 #vi /etc/profile 编辑: #Java Environment Path export JAVA_HO ...
- java jcsh执行linux命令,java jcsh执行linux命令
java jcsh执行linux命令 [2021-02-03 01:26:29] 简介: php去除nbsp的方法:首先创建一个PHP代码示例文件:然后通过"preg_replace(&q ...
- java运行linux命令程序_Java程序执行Linux命令
java程序中要执行linux命令主要依赖2个类:Process和Runtime 首先看一下Process类: ProcessBuilder.start() 和 Runtime.exec 方法创建一个 ...
- java代码执行linux命令_java执行Linux命令的方法
本文实例讲述了java执行Linux命令的方法.分享给大家供大家参考.具体实现方法如下: public class StreamGobbler extends Thread { InputStream ...
- java 代码执行linux命令
远程执行linux命令代码 代码不是在服务器部署时,但是需要执行这个服务器的linux命令 maven库 <!-- https://mvnrepository.com/artifact/ch.e ...
- Java代码执行Linux命令
说明:项目必须是部署在Linux服务器中才能生效. 1. 工具类 @Controller public class ExecuteNewFlowUtil {/*** 运行Linux命令* @autho ...
- Linux中更新java代码命令,java代码执行linux命令
1.容器需要先执行source命令,有权限限制的需要先打通互信. 2.复杂的shell命令,如重定向,需要传入数组. public void excuteLinuxCmd(String cmd) { ...
- java代码执行linux命令_怎么用java代码运行linux命令
展开全部 以下方法支持Linux和windows两个系统的命令行调用.还用到了apache的lang工具包32313133353236313431303231363533e78988e69d83313 ...
- java adb命令_从Java程序执行ADB命令
我正在使用的程序使用ADB(Android调试桥)将文件发送到手机: for (String s : files) String cmd = "adb -s 0123456789ABCDEF ...
最新文章
- 深度学习最近发现详细分析报告
- 彻底搞定IE7频繁弹出“确实允许此网页访问剪贴板吗”
- C++ return ,break,continue,关键字
- 如何从我的Android应用程序发送电子邮件?
- Scala是完全面向函数式的编程语言体现点
- expressjs如何做mysql注入_Node.js+Express+Mysql 实现增删改查
- 【操作系统】 第二章 进程的描述与控制
- MySql 存储过程 退出
- 给定一个数跟数组,将小于等于该数的数组元素放在左边,将大于该数的数组元素放在右边...
- java中的io系统详解[转]
- mybatis与data jpa
- 【MTSP】基于matlab GUI遗传算法求解多旅行商问题【含Matlab源码 935期】
- 小米球 ngrok 安装教程
- 精伦210兼容谷歌_【精伦IDR210身份证阅读器兼容火狐和谷歌浏览器】 - 太平洋安防网...
- Netlog的数据库及LAMP架构
- 【rmzt:进击的巨人三笠帅气主题】
- 电脑版微信多开,只需要三步
- 我的年终奖发了!你呢???
- Java接入支付宝支付(沙箱)
- 支持生僻字且自动识别utf-8编码的php汉字转拼音类,PHP汉字转拼音类(支持生僻字且自动识别utf-8编码)...
热门文章
- matplotlib(4)饼图
- VTK:图像方差用法实战
- opengl加载显示3D模型3d类型文件
- boost::python::converter::as_to_python_function相关的测试程序
- boost::intrusive::avl_set用法的测试程序
- boost::graph模块实现bellman算法的测试程序
- C和C++Everything教程的简介
- boost::fusion::zip用法的测试程序
- ITK:警告定向到文件
- VTK:绘图之CompareRandomGeneratorsCxx