介绍

有时候我们在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,表示调用命令将在当前程序执行的目录中执行,因此调用到其他目录中的文件和脚本最好使用绝对路径。各个参数的含义

  1. cmdarray:包含所调用命令及其参数的数组。
  2. command:一条指定的系统命令。
  3. envp:字符串数组,其中每个元素的环境变量的设置格式为name=value;如果子进程应该继承当前进程的环境,则该参数为 null。
  4. 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脚本的操作一模一样。我这里介绍另外几个方面

  1. 给脚本传递参数;
  2. 捕获调用的输出结果;
  3. 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 命令和脚本相关推荐

  1. java基础/java调用shell命令和脚本

    一.项目需求: 从某一机构获取证书,证书机构提供小工具,执行.sh脚本即可启动服务,本地调用该服务即可获取证书. 问题:linux服务器启动该服务,不能关闭.一旦关闭,服务即停止. 解决方案:java ...

  2. Hadoop概念学习系列之Java调用Shell命令和脚本,致力于hadoop/spark集群(三十六)...

    第一种:普通做法 首先,编号写WordCount.scala程序.  然后,打成jar包,命名为WC.jar.比如,我这里,是导出到windows桌面.  其次,上传到linux的桌面,再移动到hdf ...

  3. java调用shell命令并获取执行结果

    java调用shell命令并获取执行结果 使用到Process和Runtime两个类,返回值通过Process类的getInputStream()方法获取 [plain] view plain cop ...

  4. Java 调用 Shell 命令

    近日项目中有这样一个需求:系统中的外币资金调度完成以后,要将调度信息生成一个Txt文件,然后将这个Txt文件发送到另外一个系统(Kondor)中.生成文件自然使用OutputStreamWirter了 ...

  5. java操作Linux 调用shell命令,shell脚本

    1.问题 在最近做的项目当中,需要用Java调用基于python写的两个不同的模型运行并且得到实验结果: 1.在服务器上运行的文本识别模型 2.在本地Ubuntu中annacoda 虚拟环境中运行的影 ...

  6. java执行shell命令权限不够_Java调用shell脚本解决传参和权限问题的方法|chu

    1. java 执行shell java 通过 Runtime.getRuntime().exec() 方法执行 shell 的命令或 脚本,exec()方法的参数可以是脚本的路径也可以是直接的 sh ...

  7. [转载]JAVA调用Shell脚本

    FROM:http://blog.csdn.net/jj12345jj198999/article/details/11891701 在实际项目中,JAVA有时候需要调用C写出来的东西,除了JNI以外 ...

  8. java调用shell脚本_Java 执行Shell脚本指令

    一.介绍 有时候我们在Linux中运行Java程序时,需要调用一些Shell命令和脚本.而Runtime.getRuntime().exec()方法给我们提供了这个功能,而且Runtime.getRu ...

  9. java无阻塞执行脚本,JAVA调用Shell脚本-及阻塞的解决方法

    JAVA调用Shell脚本--及阻塞的解决办法 用java调用shell,使用 Process p=Runtime.getRuntime().exec(String[] cmd); Runtime.e ...

最新文章

  1. JavaScript toFixed() 方法
  2. 如何读懂并写出装逼的函数式代码
  3. C/C++中涉及存储方式的关键字:auto,static,register,extern2009-01-22 11:23auto关键字:
  4. 高斯过程回归python_基于python的高斯过程回归训练集数据扩充
  5. 【STM32】 Keil介绍、下载、安装与注册
  6. flask sqlalchemy 单表查询
  7. 进程控制块PCB简介
  8. sql server numeric 可存几位小数_CBA中的10大传奇队长,将篮球精神一直传递下去,你认识几位呢?...
  9. java的配置文件后缀,Java - 敏感配置文件位置
  10. Java线程的同步 - synchronized
  11. 睡觉老往下跑是怎么回事_孩子冬季睡觉“不老实,踢被子”,可不单纯是热,娃的苦衷要了解...
  12. 一文十大排序算法(动画图解)
  13. android 改机型玩王者,全机型60帧一键修改
  14. php获取m3u8的地址,如何获取各大平台的播放地址(获得优酷的m3u8播放地址)为例...
  15. 移动硬盘内容变成快捷方式处理
  16. STM32F103C8T6和STM32F103C6T6区别
  17. stm32运行java虚拟机_windows下的基于Eclipse的STM32开发调试环境搭建
  18. 如果您信任此演示文稿的来源_7个技巧将使您的演示文稿更上一层楼
  19. 谷歌浏览器ajax脚本出错,你好,用谷歌浏览器,发生脚本错误怎么处理。
  20. 诛仙手游服务器维护到几点,诛仙手游11月9日更新维护到几点 11.9更新了什么

热门文章

  1. 工作记录 - 使用全局变量引发的问题
  2. 不算缺钱的理想汽车通过港交所聆讯,深陷“水银门”泥潭难以自救
  3. y7000p 2020 vbios_2020年冬季千元环300公里上笼验资明细-长沙市南湖赛鸽俱乐部
  4. 当ins撞上中国风? Mars数字藏品平台探索数字藏品轻社交
  5. 使用wagon-maven-plugin插件自动部署项目
  6. 新人如何快速上手做(海外问卷)站点查?
  7. 蓝桥杯第12届java A组,《直线》
  8. 小黑前天遇到的C0000218错误
  9. 苦战 自由软件的今生前世
  10. wordpress 自动内链标签及自动内链关键字