有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

在Linux上从Java执行grep命令时总是返回null

我正在linux文件上执行java中的grep命令。以下代码总是返回null

Process p;
String matchStr="testmatch";
String output = null;
try {
    String command = "grep \""+matchStr+"\" "+ filename;
    System.out.println("Running command: " + command);

    p = Runtime.getRuntime().exec(command);

    System.out.println("***********************************");
    System.out.println("***********************************");
    System.out.println("***********************************");

    p.waitFor();
    BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));

    while (br.readLine() != null) {
        System.out.println("in while loop");
        System.out.println("in while loop");
        System.out.println("in while loop");
        System.out.println(output);
        System.out.println("***********************************");
        System.out.println("***********************************");
        System.out.println("***********************************");
        System.out.println("***********************************");

        // Process your output here
    }

    System.out.println("exit: " + p.exitValue());
    p.destroy();
} catch (Exception e) {
    e.printStackTrace();
}

若我直接grep它,它会显示输出,但从java它永远不会进入while循环。 请告诉我这里出了什么问题


共 (3) 个答案

  1. # 1 楼答案

    我最近也在努力解决一个类似的问题,我相信我找到的解决方案也能解决你的问题(尽管你的问题有点像其他人指出的那样格式不正确)

    该问题与搜索字符串周围的引号有关

    \""+matchStr+"\"
    

    javaexec命令会直接将这些内容传递给grep命令,grep不会搜索matchStr,而是会搜索“matchStr”,结果将不是您所期望的

    这也适用于以数组形式执行命令的情况,如

    final Process process = Runtime.getRuntime().exec(new String[] { "grep", "-C1000", searchString, fileName } );
    

    将普通搜索字符串传递到字符串中,但不包括引号

  2. # 2 楼答案

    把你的代码变成https://stackoverflow.com/help/mcve后,它对我有用

    此处文件不存在:

    robert@habanero:~$ rm /home/robert/greptest.txt

    robert@habanero:~$ javac GrepTest.java && java GrepTest

    Running command: grep test /home/robert/greptest.txt

    exit: 2

    现在文件确实存在,但不包含要查找的文本:

    robert@habanero:~$ echo not found > /home/robert/greptest.txt

    robert@habanero:~$ javac GrepTest.java && java GrepTest

    Running command: grep test /home/robert/greptest.txt

    exit: 1

    现在该文件已存在并包含以下文本:

    robert@habanero:~$ echo test this > /home/robert/greptest.txt

    robert@habanero:~$ javac GrepTest.java && java GrepTest

    Running command: grep test /home/robert/greptest.txt

    test this

    exit: 0

    以下是代码:

    import java.io.*;
    
    public class GrepTest {
        public static void main(String[] args) throws Exception {
            String command = "grep test /home/robert/greptest.txt";
            System.out.println("Running command: " + command);
            Process p = Runtime.getRuntime().exec(command);
            p.waitFor();
            BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
            String output;
            while ((output = br.readLine()) != null) {
                System.out.println(output);
            }
            System.out.println("exit: " + p.exitValue());
            p.destroy();
        }
    }
    
  3. # 3 楼答案

    问题是,您没有向output写入任何内容,因此它保持null。我想你必须像这样重写你的while循环

    while ((output = br.readLine()) != null) {
        // Process your output here
    }
    

    请注意,大多数样式检查都不支持这种语法,因为它的强大性

    另外,最好在while循环之后放置p.waitFor(),这样grep就不会挂在flushig std(err|out)

    更新

    此外,最好使用^{}(自起提供)而不是Runtime.getRuntime().exec(...),因为这样可以更好地控制流程,即

    final ProcessBuilder builder = new ProcessBuilder();
    builder.command("grep", matchStr, filename);
    
    // redirect stderr to stdout
    builder.redirectErrorStream(true);
    
    final Process process = builder.start();
    
    BufferedReader br = new BufferedReader(
        new InputStreamReader(process.getInputStream()));
    String output = null;
    while ((output = br.readLine()) != null) {
        System.out.println(output);
    
        // Process your output here
    }
    
    process.waitFor();