Java: No such file or directory when redirecting command line program output to /dev/null

Tomahawkd :

I'm currently working on invoking bash program using java. The bash program output too much message and I want to redirect them to /dev/null. But I encountered a weird error No such file or directory.

Here is my demo.

public static void main(String[] args) {
        try {
            // Another version I've tried:
            // Process p = Runtime.getRuntime().exec("echo a > /dev/null");
            ProcessBuilder b = new ProcessBuilder("echo a");
            // b.redirectOutput(new File("/dev/null")).redirectErrorStream(true);
            b.redirectOutput(ProcessBuilder.Redirect.to(new File("/dev/null")))
                    .redirectErrorStream(true);
            Process p = b.start();
            p.waitFor();
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
}

And the error message as follows:

java.io.IOException: Cannot run program "echo a": error=2, No such file or directory
    at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1128)
    at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1071)
    at test.main(test.java:12)
Caused by: java.io.IOException: error=2, No such file or directory
    at java.base/java.lang.ProcessImpl.forkAndExec(Native Method)
    at java.base/java.lang.ProcessImpl.<init>(ProcessImpl.java:340)
    at java.base/java.lang.ProcessImpl.start(ProcessImpl.java:271)
    at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1107)
    ... 2 more

I'm using a MacBook with Catalina, and I tried java 1.8.0_231 and 1.8.0_241 from oracle. (I couldn't use higher java version because one of the dependency of my project requires java 8).

Joni :

To ignore the output from the process, it's easier and more portable to use ProcessBuilder.Redirect.DISCARD than explicitly redirecting to a special file/device such as /dev/null.

        b.redirectOutput(ProcessBuilder.Redirect.DISCARD)
         .redirectErrorStream(true);

Forget about using Runtime.exec - that method is badly designed and hard to use safely. If you want to do input redirection with the "> /dev/null" style, you need to remember that > is a construct created by the command interpreter shell, not the operating system, and if you want to use it you must run a shell.

Runtime.getRuntime().exec(new String[] {"sh", "-c", "echo a > /dev/null"});

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=394559&siteId=1