Java执行Shell 执行重定向命令问题
最近工作需要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[]字符串数组的形式将文件以整体参数形式传进去
//ip、port是脚本用到的参数
ProcessBuilder pb = new ProcessBuilder(new String[]{"/bin/sh","-c",RUNNING_SHELL_DIR + RUNNING_SHELL_FILE,ip,port}); 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下边,然后你会发现生成的文件在这个下边