最近工作需要java调shell脚本,发现了一些问题,手动执行脚本正常,重定向的日志文件也可以正常输出,但是用java调的时候就不行,相关问题及解决如下,供参考:

如直接执行Runtime.getRuntime().exec("ls > /sdcard/1.txt");

会得到一个IOException;

因为exec不能加入重定向和管道符号。

解决方式一:

String[] cmd = { "sh", "-c", "ls > 1.txt " }; 

Runtime.getRuntime().exec(cmd);

 

如果执行的是脚本文件且用的ProcessBuilder修改方式基本相同,我把代码贴出来参考吧,格式忽略,页面不太会调:

     String RUNNING_SHELL_DIR = "/usr/share/tomcat/apache-tomcat-8.5.69/";
        String RUNNING_SHELL_FILE= "benchmarkCommand.shell";

     //问题1:手动执行没问题,但是java调的时候报权限不足,解决:修改shell脚本执行权限       
     ProcessBuilder builder = new ProcessBuilder("/bin/chmod", "755", RUNNING_SHELL_DIR + RUNNING_SHELL_FILE);
     Process process = builder.start();
    int rc = process.waitFor();

     //问题2:脚本中有通道和重定向执行失败,解决:需要加上sh -c,用String[]字符串数组的形式将文件以整体参数形式传进去

int runningStatus = 1;
        String s = null;
        try {
            Process p = pb.start();
            //将日志打印出来
            BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
            BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
            while ((s = stdInput.readLine()) != null) {
                logger.error(s);
            }
            while ((s = stdError.readLine()) != null) {
                logger.error(s);
            }

            try {
                //此方法返回的退出值的过程。按照惯例,0表示正常终止。
                runningStatus = p.waitFor();
                logger.info("===== runningStatus=" + runningStatus);
                logger.info("waiting over. ");
            } catch (InterruptedException e) {
                result.setCode(4000);
                result.setMessage("error");
                String exceptionMessage = String.format("脚本执行有报错,exception=={}",e);
                throw new InterruptedException(exceptionMessage);

            }

        } catch (IOException e) {
            result.setCode(4000);
            result.setMessage("error");
            throw new IOException(e);
        }
        if (runningStatus != 0) {
            result.setCode(4000);
            result.setMessage("error");

        }else{
            result.setCode(2000);
            result.setMessage("ok");


        }

 

问题3:执行结果状态是0,但是没发现生成重定向的关键日志文件(1.txt)

原因:路径问题,可以在脚本里加pwd看下执行路径在哪里,生成的问题件就会在哪里

解决:也不算解决,pwd后发现执行路径是根目录/bin下边,然后你会发现生成的文件在这个下边

相关文章: