zoukankan      html  css  js  c++  java
  • 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,表示调用命令将在当前程序执行的目录中执行,因此调用到其他目录中的文件和脚本最好使用绝对路径。各个参数的含义:

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

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

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

    二、调用Shell脚本

    1、获取键盘输入

    BufferedReader reader = null;
            try{
                reader = new BufferedReader(new InputStreamReader(System.in));
                System.out.println("请输入IP:");
                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程序

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    /**
     * @author :dongbl
     * @version :
     * @Description:
     * @date :9:19 2017/11/14
     */
    public class TestBash {
        public static void main(String [] args){
            BufferedReader reader = null;
            try{
                reader = new BufferedReader(new InputStreamReader(System.in));
                System.out.println("请输入IP:");
                String ip = reader.readLine();
                String bashCommand = "sh "+ "/usr/local/java/jdk1.8.0_121/lib/stopffmpeg.sh" + " ffmpeg " + ip;
    //            String bashCommand = "chmod 777 " + "/usr/local/java/jdk1.8.0_121/lib/stopffmpeg.sh" ;
    //            String bashCommand = "kill -9" + ip;
                System.out.println(bashCommand);
                Runtime runtime = Runtime.getRuntime();
                Process pro = runtime.exec(bashCommand);
                int status = pro.waitFor();
                if (status != 0)
                {
                    System.out.println("Failed to call shell's command ");
                }
    
                BufferedReader br = new BufferedReader(new InputStreamReader(pro.getInputStream()));
                StringBuffer strbr = new StringBuffer();
                String line;            
                while ((line = br.readLine())!= null)
                {                
                    strbr.append(line).append("
    ");
                }
    
                String result = strbr.toString();
                System.out.println(result);
    
            }
            catch (IOException ec)
            {
                ec.printStackTrace();
            }
            catch (InterruptedException ex){
                ex.printStackTrace();
    
            }
        }
    }

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

    三、调试心得

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

    1、构建指令不对

    1、开始指令为:

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

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

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

    2、文件格式不对

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

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

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

     

    四、参考文献

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

    2、JAVA调用Shell脚本

     

  • 相关阅读:
    cogs1538 [AHOI2005]LANE 航线规划
    cogs468 [NOI2010]超级钢琴
    [国家集训队2011]数颜色
    动态点分治总结
    点分治总结
    数论知识总结-欧拉函数
    BZOJ2683 简单题
    COGS1871 [国家集训队2011]排队(魏铭)
    LUOGU3278 [SCOI2013]多项式的运算
    BZOJ4491 我也不知道题目名字是什么
  • 原文地址:https://www.cnblogs.com/polly333/p/7832540.html
Copyright © 2011-2022 走看看