Java - 调用 Shell 命令和脚本
介绍
有时候我们在Linux中运行Java程序时,需要调用一些Shell命令和脚本。而Runtime.getRuntime().exec()方法给我们提供了这个功能,而且Runtime.getRuntime()给我们提供了以下几种exec()方法
Process exec(String command)
在单独的进程中执行指定的字符串命令。Process exec(String[] cmdarray)
在单独的进程中执行指定命令和变量。 Process exec(String[] cmdarray, String[] envp)
在指定环境的独立进程中执行指定命令和变量。 Process exec(String[] cmdarray, String[] envp, File dir)
在指定环境和工作目录的独立进程中执行指定的命令和变量。 Process exec(String command, String[] envp)
在指定环境的单独进程中执行指定的字符串命令。 Process exec(String command, String[] envp, File dir)
在有指定环境和工作目录的独立进程中执行指定的字符串命令。
其中,其实cmdarray和command差不多,同时如果参数中如果没有envp参数或设为null,表示调用命令将在当前程序执行的环境中执行;如果没有dir参数或设为null,表示调用命令将在当前程序执行的目录中执行,因此调用到其他目录中的文件和脚本最好使用绝对路径。各个参数的含义
- cmdarray:包含所调用命令及其参数的数组。
- command:一条指定的系统命令。
- envp:字符串数组,其中每个元素的环境变量的设置格式为name=value;如果子进程应该继承当前进程的环境,则该参数为 null。
- dir:子进程的工作目录;如果子进程应该继承当前进程的工作目录,则该参数为 null。
细心的读者会发现,为了执行调用操作,JVM会启一个Process,所以我们可以通过调用Process类的以下方法,得知调用操作是否正确执行
abstract int waitFor()
导致当前线程等待,如有必要,一直要等到由该 Process 对象表示的进程已经终止。
进程的出口值。根据惯例,0 表示正常终止;否则,就表示异常失败。
另外,调用某些Shell命令或脚本时,会有返回值,那么我们如果捕获这些返回值或输出呢?为了解决这个问题,Process类提供了
abstract InputStream getInputStream()
获取子进程的输入流。 最好对输入流进行缓冲。
调用Shell命令
这里为了说明问题,我仅用tar命令进行演示。tar命令是一个打包而不进行压缩的命令。同时,为了检查tar的调用是否被正常执行,我将调用waitFor()方法。
private void callCMD(String tarName, String fileName, String... workspace){try {String cmd = "tar -cf" + tarName + " " + fileName;
// String[] cmd = {"tar", "-cf", tarName, fileName};File dir = null;if(workspace[0] != null){dir = new File(workspace[0]);System.out.println(workspace[0]);}process = Runtime.getRuntime().exec(cmd, null, dir);
// process = Runtime.getRuntime().exec(cmd);int status = process.waitFor();if(status != 0){System.err.println("Failed to call shell's command and the return status's is: " + status);}}catch (Exception e){e.printStackTrace();}
}
注意:如果把命令放到一个String[]中时,必须把命令中每个部分作为一个元素存在String[]中,或者是把命令按照空格符分割得到的String[]。
String[] cmd = {"tar", "-cf", tarName, fileName}; // right
String[] cmd = {"tar -cf", tarName, fileName}; // error
为了说明dir参数的作用,我特地把该Java程序和要打包的目录hive/放在不同的目录
/root/workspace/eclipse/Test/src/edu/wzm/CallShell.java
/root/experiment/hive
如果我不设置dir或设dir为null,那么fileName不得不是相对路径,最好是绝对路径
call.callCMD("/root/experiment/hive.tar", "/root/experiment/hive", null);
// OR
call.callCMD("/root/experiment/hive.tar", "/root/experiment/hive");
如果我设置了dir指向了hive所在的父目录就好办多了
call.callCMD("hive.tar", "hive", "/root/experiment/");
调用Shell脚本
Java调用Shell命令和调用Shell脚本的操作一模一样。我这里介绍另外几个方面
- 给脚本传递参数;
- 捕获调用的输出结果;
- envp的使用。
给脚本传递参数,这个操作很简单,无非是把参数加到调用命令后面组成String,或String[]。
捕获调用输出信息,前面也提到过用Process.getInputStream()。不过,建议最好对输入流进行缓冲
BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));
另外,envp是一个String[],并且String[]中的每一个元素的形式是:name=value。如:我的Linux系统中没有以下环境变量,但是我把它们写在Java代码中,作为envp
val=2
call=Bash Shell
我要调用的Shell脚本是:/root/experiment/test.sh
#!/usr/bin/env bashargs=1
if [ $# -eq 1 ];thenargs=$1echo "The argument is: $args"
fiecho "This is a $call"
start=`date +%s`
sleep 3s
end=`date +%s`
cost=$((($end - $start) * $args * $val))
echo "Cost Time: $cost"
Java调用代码是
private void callScript(String script, String args, String... workspace){try {String cmd = "sh " + script + " " + args;
// String[] cmd = {"sh", script, "4"};File dir = null;if(workspace[0] != null){dir = new File(workspace[0]);System.out.println(workspace[0]);}String[] evnp = {"val=2", "call=Bash Shell"};process = Runtime.getRuntime().exec(cmd, evnp, dir);
// process = Runtime.getRuntime().exec(cmd);BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));String line = "";while ((line = input.readLine()) != null) {System.out.println(line);}input.close();}catch (Exception e){e.printStackTrace();}
}public static void main(String[] args) {// TODO Auto-generated method stubCallShell call = new CallShell();call.callScript("test.sh", "4", "/root/experiment/");
}
输出
/root/experiment/
The argument is: 4
This is a Bash Shell
Cost Time: 24
Hutool
- RutimeUtil 工具类(推荐使用)
Java - 调用 Shell 命令和脚本相关推荐
- java基础/java调用shell命令和脚本
一.项目需求: 从某一机构获取证书,证书机构提供小工具,执行.sh脚本即可启动服务,本地调用该服务即可获取证书. 问题:linux服务器启动该服务,不能关闭.一旦关闭,服务即停止. 解决方案:java ...
- Hadoop概念学习系列之Java调用Shell命令和脚本,致力于hadoop/spark集群(三十六)...
第一种:普通做法 首先,编号写WordCount.scala程序. 然后,打成jar包,命名为WC.jar.比如,我这里,是导出到windows桌面. 其次,上传到linux的桌面,再移动到hdf ...
- java调用shell命令并获取执行结果
java调用shell命令并获取执行结果 使用到Process和Runtime两个类,返回值通过Process类的getInputStream()方法获取 [plain] view plain cop ...
- Java 调用 Shell 命令
近日项目中有这样一个需求:系统中的外币资金调度完成以后,要将调度信息生成一个Txt文件,然后将这个Txt文件发送到另外一个系统(Kondor)中.生成文件自然使用OutputStreamWirter了 ...
- java操作Linux 调用shell命令,shell脚本
1.问题 在最近做的项目当中,需要用Java调用基于python写的两个不同的模型运行并且得到实验结果: 1.在服务器上运行的文本识别模型 2.在本地Ubuntu中annacoda 虚拟环境中运行的影 ...
- java执行shell命令权限不够_Java调用shell脚本解决传参和权限问题的方法|chu
1. java 执行shell java 通过 Runtime.getRuntime().exec() 方法执行 shell 的命令或 脚本,exec()方法的参数可以是脚本的路径也可以是直接的 sh ...
- [转载]JAVA调用Shell脚本
FROM:http://blog.csdn.net/jj12345jj198999/article/details/11891701 在实际项目中,JAVA有时候需要调用C写出来的东西,除了JNI以外 ...
- java调用shell脚本_Java 执行Shell脚本指令
一.介绍 有时候我们在Linux中运行Java程序时,需要调用一些Shell命令和脚本.而Runtime.getRuntime().exec()方法给我们提供了这个功能,而且Runtime.getRu ...
- java无阻塞执行脚本,JAVA调用Shell脚本-及阻塞的解决方法
JAVA调用Shell脚本--及阻塞的解决办法 用java调用shell,使用 Process p=Runtime.getRuntime().exec(String[] cmd); Runtime.e ...
最新文章
- JavaScript toFixed() 方法
- 如何读懂并写出装逼的函数式代码
- C/C++中涉及存储方式的关键字:auto,static,register,extern2009-01-22 11:23auto关键字:
- 高斯过程回归python_基于python的高斯过程回归训练集数据扩充
- 【STM32】 Keil介绍、下载、安装与注册
- flask sqlalchemy 单表查询
- 进程控制块PCB简介
- sql server numeric 可存几位小数_CBA中的10大传奇队长,将篮球精神一直传递下去,你认识几位呢?...
- java的配置文件后缀,Java - 敏感配置文件位置
- Java线程的同步 - synchronized
- 睡觉老往下跑是怎么回事_孩子冬季睡觉“不老实,踢被子”,可不单纯是热,娃的苦衷要了解...
- 一文十大排序算法(动画图解)
- android 改机型玩王者,全机型60帧一键修改
- php获取m3u8的地址,如何获取各大平台的播放地址(获得优酷的m3u8播放地址)为例...
- 移动硬盘内容变成快捷方式处理
- STM32F103C8T6和STM32F103C6T6区别
- stm32运行java虚拟机_windows下的基于Eclipse的STM32开发调试环境搭建
- 如果您信任此演示文稿的来源_7个技巧将使您的演示文稿更上一层楼
- 谷歌浏览器ajax脚本出错,你好,用谷歌浏览器,发生脚本错误怎么处理。
- 诛仙手游服务器维护到几点,诛仙手游11月9日更新维护到几点 11.9更新了什么