2

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.

7
  • Did you give the full path of the file to be searched? filename does it have the full variable path? Commented Sep 13, 2016 at 14:54
  • @Inian yes its full path to the file.. also its not throwing error in reading file. Commented Sep 13, 2016 at 14:54
  • 1
    Can you run the grep invoking an explicit shell sh or bash based on your preference, like String[] command = {"/bin/sh", "-c", "grep \""+matchStr+"\" " ? Commented Sep 13, 2016 at 14:58
  • ok let me try that @Inian Commented Sep 13, 2016 at 15:00
  • @Inian can you provide me example for how to add filename in this command? Commented Sep 13, 2016 at 15:16

3 Answers 3

4

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();
Sign up to request clarification or add additional context in comments.

5 Comments

actually i was using while ((output = br.readLine()) != null) this but it wasnt working
@kirti does you program prints in while loop if you change while loop?
@kiri that means that grep failed to execute. Could you run code from update to see stderr output and write it back here?
thankyou.. it started working by changing the command as suggested by @inian
This solution is better because: 1. It robustly invokes grep directly, without adding a shell evaluation step, 2. It doesn't waitFor the process before reading its output, avoiding a deadlock on long output. 3. It uses ProcessBuilder, rather than the old, iffy, unextensible Runtime.exec. +1. It DOES work when used correctly, you just have to make sure that the filename and matchstring are the literal strings you want, and not e.g. add backslashes in front of spaces in any of them
0

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

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.