背景
手上的项目属于数据库运维方面的项目,本人是属于java组,数据库DBA组,给了脚本,让执行
遇到的问题
问题1:不知道怎么写
以前没有在程序中执行过脚本,所以就到网上搜了搜,大部分给出的答案,基本都是以下两个答案
第一种,如下面这样的方法
Process p=Runtime.getRuntime().exec("命令")
p.waitFor();
第二种
ProcessBuilder builder = new ProcessBuilder("命令");
Process process = builder.start();
process.waitFor();
这两种都有多种构造方法,具体怎么使用,网上有很多的例子,不一一介绍。
方案
在这里我选择了第一种,这里看别人帖子的时候,就知道会有一些问题,如脚本执行阻塞啊,所以直接就找了对应的解决办法,用两个流来解决,具体原因暂时没有研究过,但是这个方法是没有问题,最终也可以成功的执行。
@Component
public class ExShell {
public void ex(String cmd){
Runtime rt = Runtime.getRuntime();
Process p=null;
try {
System.out.println("start le");
p = rt.exec(cmd);
//获取进程的标准输入流
final InputStream is1 = p.getInputStream();
//获取进城的错误流
final InputStream is2 = p.getErrorStream();
//启动两个线程,一个线程负责读标准输出流,另一个负责读标准错误流
new Thread() {
public void run() {
BufferedReader br1 = new BufferedReader(new InputStreamReader(is1));
try {
String line1 = null;
while ((line1 = br1.readLine()) != null) {
if (line1 != null){}
}
} catch (IOException e) {
e.printStackTrace();
}
finally{
try {
is1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}.start();
new Thread() {
public void run() {
BufferedReader br2 = new BufferedReader(new InputStreamReader(is2));
try {
String line2 = null ;
while ((line2 = br2.readLine()) != null ) {
if (line2 != null){}
}
} catch (IOException e) {
e.printStackTrace();
}
finally{
try {
is2.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}.start();
//脚本执行完才可以执行下一步
p.waitFor();
System.out.println("zhi xing wan le ");
p.destroy();
System.out.println("guan bi ");
} catch (Exception e) {
e.printStackTrace();
}
finally {
if (p!=null)
{
try {
p.getErrorStream().close();
p.getInputStream().close();
p.getOutputStream().close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
问题2:脚本执行完没有预期的结果
虽然上面的方法没有问题,但是脚本有问题,在执行一个脚本之前,一定要知道这个脚本大概的耗时,所产生的结果,本人所执行的脚本大概需要几分钟,执行完会产生一些文件,但是在调用的时候几乎立刻就结束了,但是没有报异常,也没有结果产生,因为这个脚本的执行还需要一些外在条件,所以一度认为是外在条件的问题,但其实不是,实际上是因为脚本没有执行权限,但是我的程序里没有报错,所以,这里第一个答案就是,一定要去linux上,手动执行下这个脚本,看有没有什么问题;然后脚本可以执行了。
问题3:生成的文件找不到
DBA告诉我,会在脚本所在目录下,生成一个文件夹,但是我找不到,又是一个离奇事件,后来仔细看了脚本,脚本的意思应该是,在哪里执行这个脚本,就会在当前目录下生成一个文件夹,java调用shell脚本,默认就在根目录下‘/’,去执行你那个命令,所以生成的文件也放在根目录下,也就是与root等同级,当然这只是我这的问题,具体的要看脚本。
问题4:脚本的存放位置
最开始的想法,是想把脚本和生成文件放在项目的资源路径下,但是在项目打成jar包后,没有办法获取路径,虽然可以通过流的方式读取,但是我最后是需要动态的返回生成文件的路径让前端访问的,所以就把文件一起放到linux里,无奈之举。