Farid Arshad
Farid Arshad

Reputation: 334

Exit(1) when running exec on java

I am running sed command in java program when i execute my java file in linux. when i ran the command alone in linux, this will work -> sed '1d;$d' /home/sample/testdata.txt > /home/output/testupdate.txt

however when i ran my java program in linux, its returning exit(1) error . i have read through and use as an array but its still failing .

public static void main(String[] args) {
    String[] cmd = {"sed", "sed '1d;$d' /home/sample/testdata.txt > /home/output/testupdate.txt"};
    String s;
    Process p;
    try {
        p = Runtime.getRuntime().exec(cmd);
        BufferedReader br = new BufferedReader(
                new InputStreamReader(p.getInputStream()));
        while ((s = br.readLine()) != null) {
            System.out.println("line: " + s);
        }
        p.waitFor();
        System.out.println("exit: " + p.exitValue());
        p.destroy();
    } catch (Exception e) {
    }
}

Upvotes: 0

Views: 554

Answers (2)

VGR
VGR

Reputation: 44308

You don’t need sed. Java can do everything sed can do.

In your case, it appears you are using sed to remove the first and last line from a file. Here’s how you would do that in Java:

Path source = Path.of("/home/sample/testdata.txt");
Path destination = Path.of("/home/output/testupdate.txt");

long lineCount;
try (Stream<?> lines = Files.lines(source)) {
    lineCount = lines.count();
}

long lastLine = lineCount - 1;

try (BufferedReader in = Files.newBufferedReader(source);
     BufferedReader out = Files.newBufferedWriter(destination)) {

    // Skip first line
    String line = in.readLine();

    long counter = 0;
    while ((line = in.readLine()) != null) {
        if (++counter < lastLine) {
            out.write(line);
            out.newLine();
        }
    }
}

If for some reason you absolutely need to use an external process, there are many other questions and answers which cover your mistake: > is not understood by sed. Normally, it is the shell (like bash) which interprets file redirection.

The proper way to run your command would have been:

ProcessBuilder builder =
    new ProcessBuilder("sed", "1d;$d", "/home/sample/testdata.txt");

builder.redirectOutput(new File("/home/output/testupdate.txt"));
builder.redirectError(ProcessBuilder.Redirect.INHERIT);

Process p = builder.start();

Upvotes: 2

DuncG
DuncG

Reputation: 15116

Java is not a shell so does not handle redirects - your original command only works via your Linux shell which understands ">".

You can make Java launch the shell to execute the command, say if you are using bash:

 String[] cmd = {"/bin/bash", "-c"
    , "sed '1d;$d' /home/sample/testdata.txt > /home/output/testupdate.txt"};

Alternatively see the other helpful comments which link to other pages on dealing with the redirects within the Java code, or to do it inside Java itself (such as with Files.lines / streams).

Upvotes: 2

Related Questions