java.io.IOException: Cannot run program cat /home/talha/* | grep -c TEXT_TO_SEARCH": error=2, No such file or directory尽管 通过终端执行相同的命令时没有问题 , 但 我却遇到了类似执行以下命令时的异常情况 。 我需要执行并返回以下命令的输出:
java.io.IOException: Cannot run program cat /home/talha/* | grep -c TEXT_TO_SEARCH": error=2, No such file or directory
cat /home/talha/* | grep -c TEXT_TO_SEARCH
这是使用Runtime类执行命令的方法:
Runtime
public static String executeCommand(String command) { StringBuffer output = new StringBuffer(); Process p; try { p = Runtime.getRuntime().exec(command); p.waitFor(); BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream())); String line = ""; while ((line = reader.readLine()) != null) { output.append(line + "\n"); } } catch (Exception e) { e.printStackTrace(); } return output.toString(); }
Runtime.exec不使用外壳程序(例如/bin/bash);它将命令直接传递到操作系统。这意味着将不会理解通配符(例如)*和管道(|),因为cat(像所有Unix命令一样)不会对这些字符进行任何解析。您需要使用类似
/bin/bash
*
|
cat
p = new ProcessBuilder("bash", "-c", command).start();
或者,如果出于某些奇怪的原因,您需要坚持使用过时的Runtime.exec方法:
p = Runtime.getRuntime().exec(new String[] { "bash", "-c", command });
如果只运行cat / grep命令,则应考虑放弃使用外部进程,因为Java代码可以轻松地遍历目录,从每个文件中读取行并将它们与正则表达式匹配:
Pattern pattern = Pattern.compile("TEXT_TO_SEARCH"); Charset charset = Charset.defaultCharset(); long count = 0; try (DirectoryStream<Path> dir = Files.newDirectoryStream(Paths.get("/home/talha"))) { for (Path file : dir) { count += Files.lines(file, charset).filter(pattern.asPredicate()).count(); } }
更新: 要递归读取树中的所有文件,请使用Files.walk:
try (Stream<Path> tree = Files.walk(Paths.get("/home/talha")).filter(Files::isReadable)) { Iterator<Path> i = tree.iterator(); while (i.hasNext()) { Path file = i.next(); try (Stream<String> lines = Files.lines(file, charset)) { count += lines.filter(pattern.asPredicate()).count(); } }; }