一、介绍

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

  1. Process exec(String command)
  2. 在单独的进程中执行指定的字符串命令。
  3.  
  4. Process exec(String[] cmdarray)
  5. 在单独的进程中执行指定命令和变量。
  6.  
  7. Process exec(String[] cmdarray, String[] envp)
  8. 在指定环境的独立进程中执行指定命令和变量。
  9.  
  10. Process exec(String[] cmdarray, String[] envp, File dir)
  11. 在指定环境和工作目录的独立进程中执行指定的命令和变量。
  12.  
  13. Process exec(String command, String[] envp)
  14. 在指定环境的单独进程中执行指定的字符串命令。
  15.  
  16. Process exec(String command, String[] envp, File dir)
  17. 在有指定环境和工作目录的独立进程中执行指定的字符串命令。

其中,其实cmdarray和command差不多,同时如果参数中如果没有envp参数或设为null,表示调用命令将在当前程序执行的环境中执行;如果没有dir参数或设为null,表示调用命令将在当前程序执行的目录中执行,因此调用到其他目录中的文件和脚本最好使用绝对路径。各个参数的含义:

  1. cmdarray: 包含所调用命令及其参数的数组。
  2. command: 一条指定的系统命令。
  3. envp: 字符串数组,其中每个元素的环境变量的设置格式为name=value;如果子进程应该继承当前进程的环境,则该参数为 null。
  4. dir: 子进程的工作目录;如果子进程应该继承当前进程的工作目录,则该参数为 null。

细心的读者会发现,为了执行调用操作,JVM会启一个Process,所以我们可以通过调用Process类的以下方法,得知调用操作是否正确执行:

  1. abstract int waitFor()
  2. 导致当前线程等待,如有必要,一直要等到由该 Process 对象表示的进程已经终止。

二、调用Shell脚本

1、获取键盘输入

  1. BufferedReader reader = null;
  2. try{
  3. reader = new BufferedReader(new InputStreamReader(System.in));
  4. System.out.println("请输入IP:");
  5. String ip = reader.readLine();

上述指令基本很常见:

1、创建读入器:BufferReader

2、将数据流载入BufferReader,即InputStreamReader

3、将系统输入载入InputStreamReader中

4、然后利用reader获取数据。

2、构建指令

shell运行脚本指令为 sh **.sh args,其实这个格式与java格式相同。

我的脚本为:

#!/bin/sh
#根据进程名杀死进程
echo "This is a $call"
if [ $# -lt 2 ]
then
   echo "缺少参数:procedure_name和ip"
   exit 1
fi

echo "Kill the $1 process"
PROCESS=`ps -ef|grep $1|grep $2|grep -v grep|grep -v PPID|awk '{ print $2}'`
for i in $PROCESS
do
   echo "Kill the $1 process [ $i ]" 
done

其实所有准备若当,就是无法读取里面的数据,执行shell指令,原因就是:

注意事项:

1.shell脚本必须有执行权限,比如部署后chmod -R 777 /webapps

2.shell文件,必须是UNIX格式,ANSI编码格式,否则容易出问题(可以用notepad++,编辑->文档格式转换,格式->转为ANSI格式(UNIX格式)

3、java程序

  1. import java.io.BufferedReader;
  2. import java.io.IOException;
  3. import java.io.InputStreamReader;
  4.  
  5. /**
  6. * @author :dongbl
  7. * @version :
  8. * @Description:
  9. * @date :9:19 2017/11/14
  10. */
  11. public class TestBash {
  12. public static void main(String [] args){
  13. BufferedReader reader = null;
  14. try{
  15. reader = new BufferedReader(new InputStreamReader(System.in));
  16. System.out.println("请输入IP:");
  17. String ip = reader.readLine();
  18. String bashCommand = "sh "+ "/usr/local/java/jdk1.8.0_121/lib/stopffmpeg.sh" + " ffmpeg " + ip;
  19. // String bashCommand = "chmod 777 " + "/usr/local/java/jdk1.8.0_121/lib/stopffmpeg.sh" ;
  20. // String bashCommand = "kill -9" + ip;
  21. System.out.println(bashCommand);
  22. Runtime runtime = Runtime.getRuntime();
  23. Process pro = runtime.exec(bashCommand);
  24. int status = pro.waitFor();
  25. if (status != 0)
  26. {
  27. System.out.println("Failed to call shell's command ");
  28. }
  29.  
  30. BufferedReader br = new BufferedReader(new InputStreamReader(pro.getInputStream()));
  31. StringBuffer strbr = new StringBuffer();
  32. String line;
  33. while ((line = br.readLine())!= null)
  34. {
  35. strbr.append(line).append("\n");
  36. }
  37.  
  38. String result = strbr.toString();
  39. System.out.println(result);
  40.  
  41. }
  42. catch (IOException ec)
  43. {
  44. ec.printStackTrace();
  45. }
  46. catch (InterruptedException ex){
  47. ex.printStackTrace();
  48.  
  49. }
  50. }
  51. }

其中文件路径为绝对路径,这点需要注意。

三、调试心得

在调试shell脚本执行过程中,反了几个错

1、构建指令不对

1、开始指令为:

  1. String bashCommand = "/usr/local/java/jdk1.8.0_121/lib/stopffmpeg.sh "+ " ffmpeg " + ip;
  1. 程序报错,权限不足。
  1. 2、此时修改为:
  1. String bashCommand = "chmod 777 "+"/usr/local/java/jdk1.8.0_121/lib/stopffmpeg.sh "+ " ffmpeg " + ip;

记住一定注意空格(格式)但此时依然无法指定脚本指令。3、在发现格式不对后,修改后,还是不行,此时指令为:

  1. String bashCommand = "sh "+ "/usr/local/java/jdk1.8.0_121/lib/stopffmpeg.sh" + " ffmpeg " + ip;
  1.  

2、文件格式不对

这是无法读取内容的关键原因,因为sh文件是在Windows系统下生成的,所以需要将格式修改为linux格式的,即(UNIX格式)

此时网上程序可以了,然后看到指令不同,修改指令即可以了。

最后终于调通了,看来格式经验不足啊

四、参考文献

1、java调用shell脚本并传递参数

2、JAVA调用Shell脚本

Java 执行Shell脚本指令的更多相关文章

  1. Java执行Shell脚本

    Linux 系统下采用 Java 执行 Shell 脚本,直接上代码: package com.smbea.demo; import java.io.BufferedReader; import ja ...

  2. Java执行shell脚本并返回结果两种方法的完整代码

    Java执行shell脚本并返回结果两种方法的完整代码 简单的是直接传入String字符串,这种不能执行echo 或者需要调用其他进程的命令(比如调用postfix发送邮件命令就不起作用) 执行复杂的 ...

  3. 利用java执行shell脚本

    BPMN中存在由系统执行的脚本任务,shell脚本任务也是该系统任务脚本中的一种,利用的也是由java执行shell脚本. 代码中的ProcessBuilder类,为java.lang.Process ...

  4. Java执行Shell脚本“No such file or directory” (win->Linux)异常的可能原因

    转自:http://blog.csdn.net/zlpdaisy/article/details/6134314 用Runtime.getRuntime().exec()方法执行Linux的一个She ...

  5. 关于使用java执行shell脚本获取centos的硬盘序列号和mac地址

    1.获取硬盘序列号: 新建shell脚本文件: identifier.sh, 内容为: diskdata=`fdisk -l` diskleft=${diskdata#*"identifie ...

  6. java执行shell脚本并输出执行情况

    1.脚本test.sh,置于/Users/hdwang目录下 #!/bin/sh cd /Users/hdwang echo ls:`ls` ;i<=;i++)); do + ); sleep ...

  7. java 执行 shell脚本通过mysql load data导入数据

    1:load_data_test.sh #!/bin/sh load_data_log=/mnt/load_data_test/load.log load_sql="LOAD DATA LO ...

  8. Java执行Dos-Shell脚本

    Java执行Dos-Shell脚本 1.介绍 2.调用shell脚本 2.1 获取键盘输入 2.2 构建指令 2.3 Java代码 3.Java调用Shell并传入参数 4.Java调用远程的Shel ...

  9. Java SSH远程执行Shell脚本实现(转)

    前言 此程序需要ganymed-ssh2-build210.jar包(下载地址:http://www.ganymed.ethz.ch/ssh2/) 为了调试方便,可以将\ganymed-ssh2-bu ...

随机推荐

  1. 玩玩vs Git 中国版 Gitee

    下载vs  下载 Gitee.VisualStudio.vsix https://gitee.com/GitGroup/CodeCloud.VisualStudio/attach_files 去git ...

  2. 发现一个好玩的东西 Web Scraper

    是一个 Chrome 的扩展程序,机智的小爬虫

  3. Windows UDP sockets: recvfrom() fails with error 10054

    https://stackoverflow.com/questions/34242622/windows-udp-sockets-recvfrom-fails-with-error-10054 #in ...

  4. DLL补丁劫持制作

    DLL: 由于输入表中只包含 DLL 名而没有它的路径名,因此加载程序必须在磁盘上搜索 DLL 文件.首先会尝试从当前程序所在的目录加载 DLL,如果没找到,则在Windows 系统目录中查找,最后是 ...

  5. 使用onpaste粘贴事件引起的探索

    前天项目有一个需求,在Excel文档里面直接复制商品编码,然后粘贴到页面空白处就把相应的数据加载出来.当时我是懵逼的,不知道如何下手. 以前没遇到过类似的需求,后来才想起onpaste事件 在使用on ...

  6. Linux 定位网络不通问题

    [参考文章]:ping命令入门详解 1. ipconfig / ifconfig 1. 作用: 检查本地的网络配置是否正确 2. ping 1. 作用: 一个十分好用的TCP/IP工具.它主要的功能是 ...

  7. u-boot中debug的一些总结

    研究u-boot,首要搞清楚的是代码的流程,运行流程是什么样子的呢?不知道,就看log.这就要把log信息 打开.研究u-boot的文件,发现里面是很多DEBUG宏定义的打印,这个打印着怎么打开呢? ...

  8. Scala + IntelliJ IDEA

    学习路上的新起点:大数据Scala + Spark +(HDFS + HBase),本文主要介绍下Scala的基本语法和用法吧.最后再简单介绍一种Java开发工具IntelliJ IDEA的使用. S ...

  9. Shell - 简明Shell入门15 - 调试(Debug)

    示例脚本及注释 #!/bin/bash -x for filename in t1 t2 t3 do touch $filename.txt echo "Create new file: $ ...

  10. html2canvas的踩坑之路

    html2canvas的踩坑之路 前言 早有耳闻这个html2canvas比较坑,但无奈于产品需求的压迫,必须实现html转图片的功能,自此走上了填坑之路,好在最后的效果还算令人满意,这才没有误了产品 ...