java.lang.Runtime exception"无法运行程序"

时间:2017-06-12 13:39:38

标签: java linux unix cat runtime.exec

我在执行下面的命令时遇到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类执行命令的方法:

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();
}

2 个答案:

答案 0 :(得分:3)

Runtime.exec不使用shell(比如说,/bin/bash);它将命令直接传递给操作系统。这意味着不会理解通配符,如*和管道(|),因为cat(与所有Unix命令一样)不会对这些字符进行任何解析。你需要使用像

这样的东西
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();
        }
    };
}

答案 1 :(得分:0)

$PATH是一个环境变量,它告诉系统在哪里搜索可执行程序(它是由冒号分隔的目录列表)。它通常在.bashrc.cshrc文件中设置,但仅在您登录时加载。当Java运行时,$PATH可能未设置,因为rc文件是不会自动执行,因此系统无法准确找到程序,无法准确指定程序。尝试使用/bin/cat/usr/bin/cat代替cat,看看它是否有效。如果是,$PATH就是您的问题。您可以将$PATH=/bin:/usr/bin添加到您的脚本中,或者只保留指定的目录名称(例如/bin/cat)。

仅仅因为您可以在登录会话中执行它并不意味着当您的Java程序之类的守护程序运行时它将起作用。您必须知道.bashrc.cshrc文件中的内容,有时甚至是系统文件的编写方式(/etc/bashrc),以便了解如何编写在守护程序下运行的脚本。另一个考虑因素是守护进程通常在不同用户的上下文中运行,并且也会丢弃。