Java中使用Runtime.exec()调用Linux命令mace4运行报错如何解决?
问题原因分析
- 第一个错误(
Fatal error: read_all_input, file > not found)的根本原因:>是Shell专属的重定向语法,不属于mace4程序的入参。直接将>作为参数传给Runtime.exec()时,系统会把>当做普通文件名传递给mace4,程序尝试读取名为>的文件自然失败。 - 第二个卡死问题的原因:使用
sh -c/bash -c时参数格式错误,-c选项要求后面的整段命令是单个完整字符串,不能拆分为多段参数;同时你没有读取进程的错误输出流,当进程错误输出缓冲区满后会阻塞挂起,表现为卡死。
正确实现方案
方案1:使用Shell重定向(和终端执行逻辑一致)
sh -c后面的整段命令要合并为一个字符串参数,同时要主动读取进程的标准输出、错误流避免缓冲区溢出:
// 把整段命令拼接成单个字符串传给sh -c String cmd = String.format("mace4 -c -f %s > %s", inputFileName, outputFileName); String[] args = new String[]{"sh", "-c", cmd}; try { Process proc = Runtime.getRuntime().exec(args, null, new File("/home/user/workDirectory/")); // 单独线程读取标准输出,避免阻塞 new Thread(() -> { try (BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()))) { String s; while ((s = br.readLine()) != null) { System.out.println("output: " + s); } } catch (IOException e) { e.printStackTrace(); } }).start(); // 单独线程读取错误输出,避免阻塞 new Thread(() -> { try (BufferedReader br = new BufferedReader(new InputStreamReader(proc.getErrorStream()))) { String s; while ((s = br.readLine()) != null) { System.err.println("error: " + s); } } catch (IOException e) { e.printStackTrace(); } }).start(); // 等待进程执行完成 int exitCode = proc.waitFor(); System.out.println("进程执行结束,退出码:" + exitCode); proc.destroy(); } catch (IOException | InterruptedException e) { e.printStackTrace(); }
方案2:Java层面处理输出(不依赖Shell,兼容性更好)
不使用Shell重定向语法,直接读取mace4的标准输出写入到目标文件:
String[] args = new String[]{"mace4", "-c", "-f", inputFileName}; try { Process proc = Runtime.getRuntime().exec(args, null, new File("/home/user/workDirectory/")); // 读取进程输出直接写入目标文件 try (InputStream in = proc.getInputStream(); FileOutputStream out = new FileOutputStream(new File("/home/user/workDirectory/", outputFileName))) { byte[] buffer = new byte[1024]; int len; while ((len = in.read(buffer)) != -1) { out.write(buffer, 0, len); } } // 读取错误流避免阻塞 try (BufferedReader br = new BufferedReader(new InputStreamReader(proc.getErrorStream()))) { String s; while ((s = br.readLine()) != null) { System.err.println("error: " + s); } } int exitCode = proc.waitFor(); System.out.println("进程执行结束,退出码:" + exitCode); proc.destroy(); } catch (IOException | InterruptedException e) { e.printStackTrace(); }
内容的提问来源于stack exchange,提问作者Lung Mihai
相关产品推荐
相关产品推荐

