Why does my java code execute bash commands incorrectly?

I tried to make my java program interact with Linux bash, but something went wrong I have a simple executable prog that reads an integer from stdin and outputs its square implement

echo 5 | ./prog

Print the correct answer from bash itself 25 in standard output but run

import java.io.*;

public class Main {
    public static void main(String[] args) throws InterruptedException,IOException {
        Runtime run = Runtime.getRuntime();
        Process proc = run.exec("echo 5 | ./prog");
        proc.waitFor();
        BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
        while(br.ready())
            System.out.println(br.readLine());
    }
}

Unexpectedly gave 5 |/ prog. What is the solution?

Solution

Java exec cannot run shell commands like this If you want to run a shell command, you need to explicitly call the shell; for example

Process proc = run.exec(new String[]{"/bin/sh","-c","echo 5 | ./prog"});

For more details on how Java handles this problem, please read the Javadoc. For exec (string) and exec (string []) Please note that these are "convenient methods". You need to follow the link chain to the underlying methods in order to fully understand what Javadoc says

If you want to know more details about how Java handles this problem, then source code

If you want to understand why Java itself does not deal with shell syntax, you may need to delve into the architecture and principles of UNIX / Linux systems, as well as the separation of concerns among applications, operating systems and command shells Please note that there are countless different shells, and each shell has (possibly) different rules for reference, parameter splitting, redirection, pipeline, etc Most popular shells are similar, but that's how things develop

Explanation of solution:

>The reason for manually splitting a command is that exec (string) does not correctly split the command into a single command and parameter It can't This is an example of two commands in a pipeline. > The reason for using "sh" is... Well... You need a shell to parse and process the shell command line Java's exec command does not support shell Syntax... As explained by Javadoc. > The purpose of the "- C" option is explained by "man sh" Basically, SH - C "a B C" means "use 'sh' to run the command line 'a B C'"

Fwiw, technically, can only build and run pipelines in Java (i.e. independent of shells), but it is usually not worth the effort You've introduced platform dependencies by running external commands, so additional dependencies in the form of specific shell commands and syntax won't make things worse

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>