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

本文介绍了Java如何通过Runtime.getRuntime().exec()方法调用Shell脚本,详细解析了各种exec()方法的参数及含义,并给出了调用Shell脚本的示例,包括获取键盘输入、构建指令、执行脚本的注意事项,以及在调试过程中的常见错误和解决办法。
摘要由CSDN通过智能技术生成

一、介绍

有时候我们在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 intwaitFor()

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

二、调用Shell脚本

1、获取键盘输入

BufferedReader reader = null;try{

reader= new BufferedReader(newInputStreamReader(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程序

importjava.io.BufferedReader;importjava.io.IOException;importjava.io.InputStreamReader;/***@author:dongbl

*@version:

* @Description:

* @date :9:19 2017/11/14*/

public classTestBash {public static voidmain(String [] args){

BufferedReader reader= null;try{

reader= new BufferedReader(newInputStreamReader(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(newInputStreamReader(pro.getInputStream()));

StringBuffer strbr= newStringBuffer();

String line;while ((line = br.readLine())!= null)

{

strbr.append(line).append("\n");

}

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格式)

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

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

四、参考文献

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值