【需求】:
在版本管理中,将版本文件上传至服务器60,上传成功后,因为终端升级需要,要将版本文件分割成包,并且上传至另外一个服务器64,这里的两个操作需要调用shell来完成,那么,需求来了,在Java web应用中,如果调用shell去执行操作,以及能够正确的传递参数给shell和获取shell执行之后返回的信息?
【解决办法】:
在没有看这一块之前,以为这里会比较复杂的,看了之后简单的令我惊讶,在Java
中有现成的类提供执行命令:Runtime
。
Runtime.
getRuntime().exec(com);
说明:com为字符串类型参数,表示执行的shell名,为全路径
仅此一行代码,便完成了对shell
命令的执行操作。但是仅仅执行当然不够,就拿本次需求来说,shell
执行的时候需要知道分割文件的文件名,需要知道这个文件的大小,需要知道分割之后以什么名字来保存,这些需要由调用者告诉shell
,以便shell
来执行,那么如何传递参数给shell
呢?
来看下getRuntime().exec()
的重载方法,如下图:
![](http://192.85.1.133/dlog/data/attachment/forum/201412/08/160107n8hopncdk851if1w.jpg)
重载参见API
中对exec
的描述,由API
可知,在调用需要传参的shell
时,将参数放到String
数组中传递给shell
,由shell
使用,在shell
中使用$0…n
进行获取。
String [] com = { "/usr/local/tomcat6/bin/lavt.sh","5","10"};
Processps = rt.exec(com);
传递完参数,那怎么知道shell
执行的成功与否呢?通常的方法是将执行结果在shell
中通过echo
打印到终端上,然后使用流读取打印信息,然后读取到父进程输出。如果这里不明白,继续看。
在这里要用到另外一个类Process
进程类,原因是Runtime.getRuntime().exec()
执行时开启了新的进程。属于应用进程的子进程,应用进程属于父进程。子进程中的信息父进程不能直接获取,需要先读取子进程的信息,然后在父进程中输出。
Process ps = rt.exec(com);
接下来ps
能够获取到输入流,在使用流将该信息进行读取。
至此,java web中调用带参shell,获取shell返回信息解决。
【完成代码示例】:
Runtime rt = Runtime.
getRuntime();
//definition the parameter for shell
String [] com = { "/usr/local/tomcat6/bin/lavt.sh","5","10"};
//get the object of process
Process ps = rt.exec(com);
BufferedInputStream in =
new BufferedInputStream(ps.getInputStream());
BufferedReader br =
new BufferedReader(
new InputStreamReader(in));
String mes ;
res.add("ExecSuccess !!!");
while((mes = br.readLine()) !=
null){
res.add(mes);
}
【注意事项】:
1. 调用shell是,传递的参数,shell名为该shell文件的全路径文件名,在使用的时候为了方便可以写到配置文件中,读取传入。
2. 接第1点,shell中的参数也可以作为配置文件参数进行读取
3. 关于shell中传入参数的顺序需要注意,传入参数是String类型,不会在shell中判断,因此shell中使用的参数顺序要正确
4. 对shell返回值的定义,因为是echo打印信息,所以打印信息的格式要预先定义好,这样对于返回信息的读取解析会更为方便。