简体   繁体   中英

How to run a shell command in the calling (current) shell with Java

Suppose something like this:

execInCurrentShell("cd /")
System.out.println("Ran command : cd /")

is in the main() function of MyClass

So that when I run the class, I cd into the / directory

user@comp [~] pwd
/Users/user
user@comp [~] java MyClass
Ran command : cd /
user@comp [/] pwd
/

The usual way to run shell commands, that is, through the Runtime class:

Runtime.getRuntime().exec("cd /")

Won't work here because it doesn't run the command in the current shell but in a new shell.

What would the execInCurrentShell() function (the one that actually works) look like?

You won't be able to run commands that affect the current invoking shell, only to run command line bash/cmd as sub-process from Java and send them commands as follows. I would not recommend this approach:

String[] cmd = new String[] { "/bin/bash" }; // "CMD.EXE"
ProcessBuilder pb = new ProcessBuilder(cmd);

Path out = Path.of(cmd[0]+"-stdout.log");
Path err = Path.of(cmd[0]+"-stderr.log");
pb.redirectOutput(out.toFile());
pb.redirectError(err.toFile());

Process p = pb.start();
String lineSep = System.lineSeparator(); 

try(PrintStream stdin = new PrintStream(p.getOutputStream(), true))
{
    stdin.print("pwd");
    stdin.print(lineSep);
    stdin.print("cd ..");
    stdin.print(lineSep);
    stdin.print("pwd");
    stdin.print(lineSep);
};
p.waitFor();
System.out.println("OUTPUT:"+Files.readString(out));
System.out.println("ERROR WAS: "+Files.readString(err));

}

This also works for CMD.EXE on Windows (with different commands). To capture the response per command you should replace use of pb.redirectOutput() with code to read pb.getInputStream() if you really need the responses per line rather than as one file.

On Windows to start a command shell from Java program, you can do it as follows:

import java.io.IOException;

public class Command {
    public static void main(String[] args) {
        try {
            Runtime.getRuntime().exec("cmd.exe /c start");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

You need to use the same approach for Linux.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM