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_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);
- }
- }
- }
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命令、脚本,支持程序在服务器上使用linux命令。工具类为:ProcessUtil,支持单个命令和批量命令执行函数,同时在工具类中添加了getFileLineNumByCmd函数支持通过linux命令获取文件行数的样例。
http://www.ganymed.ethz.ch/ssh2/在这个网址下载一个调用ssh和scp命令的jar包。 然后,就可以写程序了。将上面的jar包导入MyEclipse,附一个类的实例代码。
自己做的小程序,仅供参考, 说明:链接amq,被动接受amq消息,登录linux,执行指令
Java应用程序远程登录linux并执行其命令.pdf
ps -ef |grep java|grep
主要介绍了Java远程连接Linux服务器并执行命令及上传文件功能,本文是小编整理的代码笔记,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
本文通过图文并茂的方式给大家介绍linux下执行java程序的方法,想要在Ubuntu上运行java程序,可以将java程序编译成功后打包,然后在Ubuntu上用命令执行jar文件,具体详情请参考本
android的程序基于java开发,当我们接上调试器,执行adb shell,就可以执行linux命令,但是却并不能执行java命令。 那么在android的shell中是否就不能执行java程序了呢。 答案是否定的。我们可以通过app_process来...
可在linux下执行的txt格式转换成pdf格式的可执行程序。 原创小程序,linux下只要安装jdk1.6版本或以上可用, 如果想把A.txt文件转换成A.pdf文件,那么执行命令为: java -jar txtToPDF_fat.jar A.txt A.pdf
ping 在Java中Linux中执行ping的服务器-客户端实现==================================系统要求运行该应用程序的系统必须已安装Java 8。==================================编译下载项目。 如果要从那里运行它,请...
java ping ip ping命令 ping工具类 支持linux和windows等所有平台 Ping是Windows下的一个命令 在Unix和Linux下也有这个命令。 ping也属于一个通信协议,是TCP/IP协议的一部分 利用“ping”命令可以检查网络是否连通...
JAVA操作linux服务器,本文用于启动shell脚本并返回数据,简单易懂,可随时修改,1.连接服务器。2.输入服务器地址。3.输入用户名和密码。4.输入要执行的命令。
JavaShell 命令 用于在 windows 和 linux 上执行 shell 命令的 Java 实用程序
ffmpeg.exe能解析的格式:(asx,asf,mpg,wmv,3gp,mp4,mov,avi,flv等) 对ffmpeg.exe无法解析的文件格式(wmv9,rm,rmvb等), 可以先用别的工具(mencoder)转换为avi(ffmpeg能解析的)格式;...
此时会生成文件jdk-1_5_0_02-linux-i586.rpm,同样给所有用户添加可执行的权限 #chmod +x jdk-1_5_0_02-linux-i586.rpm 安装程序 #rpm -ivh jdk-1_5_0_02-linux-i586.rpm 出现安装协议等,按接受即可。 2.设置环境...
linux中java项目需要重启一般使用先找到进程杀掉进程,然后找到项目启动,整个过程不算复杂,但是每次都操作一遍太麻烦,我这里把这个过程整理成shell脚本,大家可以修改里面项目名称,每次直接执行这个命令重启项目...
这是Linux环境下一键启动/停止多个Java程序jar包的文件,执行命令为./java.sh start
在Java程序中调用Unix/Linux主机上的Shell命令,并返回相应执行结果。