kirti
kirti

Reputation: 4609

Executing grep command on Linux from Java always returning null

I am executing grep command from java on a linux file. Its always returning null for the following code.

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

If i grep it directly it shows output but from java it never gets into while loop. Please suggest whats wrong here.

Upvotes: 2

Views: 1895

Answers (3)

Martin
Martin

Reputation: 1435

I was recently struggling with a similar issue, and I believe I the solution I found is an answer also to your problem (though your question is a bit malformed as others have pointed out).

The issue pertrains to the quote marks around your search string,

\""+matchStr+"\"

The java exec command will literally deliver these to the grep command, and instead of searching for matchStr, grep will be looking for "matchStr", and the results will not be what you are expecting.

This applies also in case one is executing the command as an array like

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

Pass the plain searchString without including quotation marks into the string.

Upvotes: 0

Robert
Robert

Reputation: 8618

After turning your code into a https://stackoverflow.com/help/mcve it works for me.

Here the file does not exist:

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

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

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

exit: 2

Now the file does exist but does not contain the text to be found:

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

Now the file exists and contains the text:

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

Here is the code:

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

Upvotes: 0

vsminkov
vsminkov

Reputation: 11260

The problem is that you do not write anything to output so it stays null. I guess you have to rewrite your while loop like this

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

Take a note that this syntax is discouraged by most style check due to it's abmiguity

Also it's a good idea to place p.waitFor() after while loop so grep would not hang on flushig std(err|out).

UPDATE

Also it is a good idea to use ProcessBuilder (available since ) instead of Runtime.getRuntime().exec(...) because you will have more control over the process i.e

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

Upvotes: 4

Related Questions