0

I am trying to run this command from java code and expecting a file to be generated with 1 liner code :

cut -d , -f 2  /online/data/test/output/2Zip/brita_ids-*.csv | sort -u | tr -d '\n' | sha512sum > /online/data/test/output/file_name.txt

This cmd is fine when I am running from cmd line but something wrong with my java code that I gatting hard time to figure out and I am not seeing the expected file being generated. Any clue whay may have happened here?

Here is my code to generate that file :

public String executeCommand(String command) {

    StringBuffer output = new StringBuffer();

    Process p;
    try {
        LOG.info( "Executing cmd : " + command  );
        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();
        LOG.error( "Error in executing cmd : " + command + " \nError : " + e.getMessage() );
    }

    return output.toString();

}

Thanks in advance.

VictorGram
  • 2,199
  • 4
  • 31
  • 59
  • what is the error you are getting ? – Shriram Sep 25 '15 at 17:38
  • It would probably be better to 1) use a ProcessBuilder and 2) use a collection of Strings for your command, not a single String. Note that you don't show how you call this method. – Hovercraft Full Of Eels Sep 25 '15 at 17:38
  • @patty read errors using `getErrorStream()` – Madhawa Priyashantha Sep 25 '15 at 17:40
  • Please show us the value of `command`. If possible, try to print it to console. It should look exactly like the text you are using when using console. – npinti Sep 25 '15 at 17:45
  • 2
    You are using shell syntax (pipes, asterisks) but apparently you are not running this with a shell, so all of those are just considered literal arguments to the command. You should run it in an actual shell. – RealSkeptic Sep 25 '15 at 17:45
  • Better to use ProcessBuilder to redirect the error stream to be merged with the standard output of the folking process, so that error information can be read by using getInputStream(). This may give you clues about your program failure. And just print the output of the executing process once you get it from the input stream. Since you are using '|' in your command, if you choose to use ProcessBuilder, do like this : params.add("sh");params.add("-c");params.add(command); ProcessBuilder pb = new ProcessBuilder(params); – qingl97 Sep 25 '15 at 17:52
  • **With the change it worked but has different result than running this cmd directly on the shell. Any idea - what could be th reason and what can be done?** – VictorGram Sep 25 '15 at 19:55

3 Answers3

0

Thank you all, specifically @RealSkeptic and @qingl97. With your suggestion, I made a small change and that worked.

Process p = Runtime.getRuntime().exec(
          new String[]{"sh","-c",command});

 p.waitFor()
VictorGram
  • 2,199
  • 4
  • 31
  • 59
0

Try this if you want to get the output as well. ProcessBuilder would be better for multiple arguments and commans

 try {
        Process process = Runtime
                .getRuntime()
                .exec("cut -d , -f 2  /online/data/test/output/2Zip/brita_ids-*.csv | sort -u | tr -d '\n' | sha512sum > /online/data/test/output/file_name.txt");
        process.waitFor();
        BufferedReader reader = new BufferedReader(new InputStreamReader(
                process.getInputStream()));
        String line = reader.readLine();
        while (line != null) {
            // print the output to Console
            System.out.println(line);
            line = reader.readLine();
        }

    } catch (Exception e1) {
        e1.printStackTrace();
    } 
    System.out.println("Finished");

Something like this if you want a series of commands

 ProcessBuilder builder = new ProcessBuilder(
        "cmd.exe", "/c", "cd \"C:\\Program Files\\Microsoft SQL Server\" && dir");
    builder.redirectErrorStream(true);
    Process p = builder.start();
    BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
    String line;
    while (true) {
        line = r.readLine();
        if (line == null) { break; }
        System.out.println(line);
    }

From SOQuestion

Community
  • 1
  • 1
Zuko
  • 2,276
  • 24
  • 27
0

As RealSkeptic pointed out, pipe characters (|) are not command arguments; they're interpreted by a shell. And you are calling a command (cut) directly rather than using a shell.

This isn't a direct answer to your question, but you can accomplish your task without any shell commands:

Charset charset = Charset.defaultCharset();
MessageDigest digest = MessageDigest.getInstance("SHA-512");

try (DirectoryStream<Path> dir = Files.newDirectoryStream(
        Paths.get("/online/data/test/output/2Zip"), "brita_ids-*.csv")) {

    for (Path file : dir) {
        Files.lines(file, charset)
            .map(line -> line.split(",")[1])
            .sorted(Collator.getInstance()).distinct()
            .forEach(value -> digest.update(value.getBytes(charset)));
    }
}

byte[] sum = digest.digest();

String outputFile = "/online/data/test/output/file_name.txt";
try (Formatter outputFormatter = new Formatter(outputFile)) {
    for (byte sumByte : sum) {
        outputFormatter.format("%02x", sumByte);
    }
    outputFormatter.format(" *%s%n", outputFile);
}
VGR
  • 33,718
  • 4
  • 37
  • 50