【需求】:
在版本管理中,将版本文件上传至服务器60,上传成功后,因为终端升级需要,要将版本文件分割成包,并且上传至另外一个服务器64,这里的两个操作需要调用shell来完成,那么,需求来了,在Java web应用中,如果调用shell去执行操作,以及能够正确的传递参数给shell和获取shell执行之后返回的信息?
【解决办法】:
在没有看这一块之前,以为这里会比较复杂的,看了之后简单的令我惊讶,在Java中有现成的类提供执行命令:Runtime。
Runtime.getRuntime().exec(com);
说明:com为字符串类型参数,表示执行的shell名,为全路径
仅此一行代码,便完成了对shell命令的执行操作。但是仅仅执行当然不够,就拿本次需求来说,shell执行的时候需要知道分割文件的文件名,需要知道这个文件的大小,需要知道分割之后以什么名字来保存,这些需要由调用者告诉shell,以便shell来执行,那么如何传递参数给shell呢?
来看下getRuntime().exec()的重载方法,如下图:

重载参见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打印信息,所以打印信息的格式要预先定义好,这样对于返回信息的读取解析会更为方便。