当前位置: 首页 > 知识库问答 >
问题:

在Java中运行Bash命令

邢嘉祯
2023-03-14

我有下面的课。它允许我通过java执行命令。

public class ExecuteShellCommand {

public String executeCommand(String command) {

    StringBuffer output = new StringBuffer();

    Process p;
    try {
        p = Runtime.getRuntime().exec(command);
        p.waitFor();
        BufferedReader reader = 
                        new BufferedReader(new InputStreamReader(p.getInputStream()));

        String line = "";           
        while ((line = reader.readLine())!= null) {
            output.append(line + "\n");
        }

    } catch (Exception e) {
        e.printStackTrace();
    }

    return output.toString();

}

}

当我运行命令时,上一个命令的结果没有保存。例如:

public static void main(String args[]) {

    ExecuteShellCommand com = new ExecuteShellCommand();
    System.out.println(com.executeCommand("ls"));
    System.out.println(com.executeCommand("cd bin"));
    System.out.println(com.executeCommand("ls"));

}

给出输出:

bin
src


bin
src

为什么第二个“ls”命令不显示“bin”目录的内容?

共有3个答案

唐昊焜
2023-03-14

每个调用都在自己的shell中执行。因此,第三次调用看不到第二次调用的“cd”。

参见:https://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html#exec(java.lang.字符串)。

这表示命令在单独的进程中运行。因此,您产生了3个进程。

如果您希望所有3个都在同一个过程中,请尝试以下操作:

com.executeCommand("ls; cd bin; ls");
郑俊材
2023-03-14

您可以形成一个复杂的 bash 命令来执行所有操作:“ls;光盘箱;ls”。要完成这项工作,您需要显式调用 bash。这种方法应该为您提供 bash 命令行的所有功能(报价处理、$ 扩展、管道等)。

/**
 * Execute a bash command. We can handle complex bash commands including
 * multiple executions (; | && ||), quotes, expansions ($), escapes (\), e.g.:
 *     "cd /abc/def; mv ghi 'older ghi '$(whoami)"
 * @param command
 * @return true if bash got started, but your command may have failed.
 */
public static boolean executeBashCommand(String command) {
    boolean success = false;
    System.out.println("Executing BASH command:\n   " + command);
    Runtime r = Runtime.getRuntime();
    // Use bash -c so we can handle things like multi commands separated by ; and
    // things like quotes, $, |, and \. My tests show that command comes as
    // one argument to bash, so we do not need to quote it to make it one thing.
    // Also, exec may object if it does not have an executable file as the first thing,
    // so having bash here makes it happy provided bash is installed and in path.
    String[] commands = {"bash", "-c", command};
    try {
        Process p = r.exec(commands);

        p.waitFor();
        BufferedReader b = new BufferedReader(new InputStreamReader(p.getInputStream()));
        String line = "";

        while ((line = b.readLine()) != null) {
            System.out.println(line);
        }

        b.close();
        success = true;
    } catch (Exception e) {
        System.err.println("Failed to execute bash with command: " + command);
        e.printStackTrace();
    }
    return success;
}
锺功
2023-03-14

使用< code > runtime . exec(command)启动一个新进程。每个进程都有一个工作目录。这通常是启动父进程的目录,但是您可以更改启动进程的目录。

我建议使用ProcessBuilder

ProcessBuilder pb = new ProcessBuilder("ls");
pb.inheritIO();
pb.directory(new File("bin"));
pb.start();

如果您想在一个shell中运行多个命令,最好创建一个临时外壳脚本并运行它。

public void executeCommands() throws IOException {

    File tempScript = createTempScript();

    try {
        ProcessBuilder pb = new ProcessBuilder("bash", tempScript.toString());
        pb.inheritIO();
        Process process = pb.start();
        process.waitFor();
    } finally {
        tempScript.delete();
    }
}

public File createTempScript() throws IOException {
    File tempScript = File.createTempFile("script", null);

    Writer streamWriter = new OutputStreamWriter(new FileOutputStream(
            tempScript));
    PrintWriter printWriter = new PrintWriter(streamWriter);

    printWriter.println("#!/bin/bash");
    printWriter.println("cd bin");
    printWriter.println("ls");

    printWriter.close();

    return tempScript;
}

当然,您也可以在您的系统上使用任何其他脚本。在运行时生成脚本有时是有意义的,例如,如果执行的命令必须改变。但是您应该首先尝试创建一个可以用参数调用的脚本,而不是在运行时动态生成。

如果脚本生成很复杂,使用velocity这样的模板引擎也是合理的。

编辑

您还应该考虑将流程构建器的复杂性隐藏在一个简单的接口后面。

将您需要的内容(接口)与完成方式(实现)分开。

public interface FileUtils {
    public String[] listFiles(String dirpath);
}

然后,您可以提供使用process builder或本机方法来完成工作的实现,并且您可以为不同的环境(如linux或windows)提供不同的实现。

最后,这样的接口也更容易在单元测试中被模仿。

 类似资料:
  • 问题内容: 我运行一个包含此行的python脚本 然后,我在服务器上运行相同的代码,并收到以下错误消息 因此,我要做的就是print bashCommand在运行之前,在终端中插入一个比命令更清晰的信息os.system()。 当然,我再次收到错误(由引起os.system(bashCommand)),但是在该错误出现之前,它会在终端中打印命令。然后我只是复制了输出,然后将复制粘贴到终端中,然后按

  • 问题内容: 有没有办法从Python运行BASH内置命令? 我试过了: 及其许多变化。我想跑步还是。 问题答案: 我终于找到了可行的解决方案。 谢谢大家的投入。

  • 我在Windows上使用java,想调用Linux命令,所以我尝试打开git bash并粘贴一些命令。我可以打开git bash,但不能粘贴任何内容。 这将打开git bash罚款: 当我这样做时,git bash打开但立即关闭:

  • 我有这个命令来编译我的程序。 我创建了以下makefile。 如果从terminal运行该命令将成功,但make将失败。 它将失败,并出现错误 该文件应该在命令中使用导入。 我认为Makefile中的命令执行起来很像bash脚本。 在bash中运行命令和在Makefile中运行命令有什么区别?

  • 问题内容: 自寻找以来已经有一段时间了,但找不到解决方案。我试图在.jar文件中的Linux上执行bash命令。为此,我尝试了很多事情,包括: 因此,当我单击.jar文件时,我希望程序打开bash并执行命令(java -jar …),以执行程序的另一部分。 关于如何做的任何想法? 问题答案: 要了解这一点,您首先需要了解如何在shell提示符下运行该命令。 请注意双引号在哪里。第一个参数是。第二个

  • 问题内容: 有没有办法在Java应用程序中运行此命令行? 我可以用命令运行它,但是我不能在Java中运行它。 问题答案: