java调用shell脚本并传递参数

最近业务上需要java调用执行shell脚本进行一些业务处理,写了个demo,记录下。

主要代码

    @RequestMapping("/copy/database")
    @ResponseBody
    public String copyDatabase(HttpServletRequest request,String dbCode,String targetPath){
        JSONObject result = new JSONObject();
        
        String osname = System.getProperty("os.name");
        if ((osname != null) && (osname.toLowerCase().startsWith("win"))){
            LOG.info("当前操作系统是:"+osname);
            result.put("code", "0");
            result.put("msg", "当前服务器操作系统不是linux");
            return result.toJSONString();
        }
        LOG.info("接收到参数:dbCode=" + dbCode + " targetDbNfsPath=" + targetPath);
        if(StringUtil.isBlank(dbCode) || StringUtil.isBlank(targetPath)){
            result.put("code", "0");
            result.put("msg", "dbCode/targetPath不能为空");
            return result.toJSONString();
        }
        
        String dir = DbDirConstant.findDir(dbCode);
        if(StringUtil.isBlank(dir)){
            result.put("code", "0");
            result.put("msg", "根据dbCode找不到对应的数据库目录");
            return result.toJSONString();
        }
        //脚本路径
        String shellPath = request.getServletContext().getRealPath("/")+"WEB-INF/classes";
        String cmd = shellPath + "/copyDB.sh "+ dir + " " + targetPath;
        ProcessBuilder builder = new ProcessBuilder("/bin/sh","-c",cmd);
        builder.directory(new File(shellPath));
        
        int runningStatus = 0;
        String s = null;
        StringBuffer sb = new StringBuffer();
        try {
            Process p = builder.start();
            
            BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
            BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
            while ((s = stdInput.readLine()) != null) {
                LOG.info("shell log info ...." + s);
                sb.append(s);
            }
            while ((s = stdError.readLine()) != null) {
                LOG.error("shell log error...." + s);
                sb.append(s);
            }
            try {
                runningStatus = p.waitFor();
            } catch (InterruptedException e) {
                runningStatus = 1;
                LOG.error("等待shell脚本执行状态时,报错...",e);
                sb.append(e.getMessage());
            }
            
            closeStream(stdInput);
            closeStream(stdError);
            
        } catch (Exception e) {
            LOG.error("执行shell脚本出错...",e);
            sb.append(e.getMessage());
            runningStatus =1;
        }
        LOG.info("runningStatus = " + runningStatus);
        if(runningStatus == 0){
            //成功
            result.put("code", "1");
            result.put("msg", "成功");
            return result.toJSONString();
        }else{
            result.put("code", "0");
            result.put("msg", "调用shell脚本复制数据库时失败..." + sb.toString());
            return result.toJSONString();
        }
    }
    
    private void closeStream(BufferedReader reader){
        try {
            if(reader != null){
                reader.close();
            }
        } catch (Exception e) {
            reader = null;
        }
    }

其中shell

#!/bin/bash

echo 'copy db start....'

dbBack=/databaseBack
nfsDir=/targetDbNfs
state=0

cd /

if [ ! -d "$nfsDir" ];then
  mkdir -p $nfsDir
fi

## mount target db
echo 'ready mount target db...'
mount -t nfs $2 $nfsDir

if [ $? -eq 0 ]
  then
    echo 'mount target db success...'
  else
    echo 'mount target db fail...'
    exit 1
fi

echo 'ready copy....'
## cp will tip y/n, so use \cp 
\cp -rf $dbBack/$1/* $nfsDir/

if [ $? -eq 0 ]
  then
    echo 'copy success...'
  else
    echo 'copy fail...'
    $state=1
fi

umount $nfsDir

exit $state

注意事项:
1.shell脚本必须有执行权限,比如部署后chmod -R 777 /webapps

2.shell文件,必须是UNIX格式,ANSI编码格式,否则容易出问题(可以用notepad++,编辑->文档格式转换,格式->转为ANSI格式
 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值