简体   繁体   English

如何在调用(当前)shell 和 Java 中运行 shell 命令

[英]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 MyClassMyClassmain() function 中

So that when I run the class, I cd into the / directory这样当我运行 class 时,我cd进入/目录

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:运行shell命令的常用方式,即通过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.在这里不起作用,因为它不在当前 shell 中运行命令,而是在新 shell 中运行命令。

What would the execInCurrentShell() function (the one that actually works) look like? execInCurrentShell() function(实际工作的那个)会是什么样子?

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.您将无法运行影响当前调用 shell 的命令,只能从 Java 将命令行 bash/cmd 作为子进程运行并向它们发送命令,如下所示。 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).这也适用于 Windows 上的 CMD.EXE(使用不同的命令)。 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.要捕获每个命令的响应,如果您确实需要每行而不是一个文件的响应,则应将pb.redirectOutput()的使用替换为读取 pb.getInputStream() 的代码。

On Windows to start a command shell from Java program, you can do it as follows:在 Windows 上从 Java 程序启动一个命令 shell,你可以这样做:

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.您需要对 Linux 使用相同的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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