【问题标题】:Running bash file from Java is not working从 Java 运行 bash 文件不起作用
【发布时间】:2025-12-01 17:55:01
【问题描述】:
try{

        //String[] cmd = new String[]{"/bin/sh", "send.sh"};
        //Process pr = Runtime.getRuntime().exec(cmd);  //nothing happens           
        //Process p = Runtime.getRuntime().exec("send.sh"); //File not found
        //Process p = Runtime.getRuntime().exec("bash send.sh"); //nothing happens

        // ProcessBuilder pb = new ProcessBuilder("bash","send.sh");
        // Process p = pb.start(); //nothing happens

    }
    catch(Throwable t)
    {
        t.printStackTrace();
    }

通过这段代码,我试图启动一个位于程序目录中的简单 bash 文件。当我用 shell 启动它或简单地执行它时,bash 文件的代码就可以工作。 bash 文件的代码有效。

我已经尝试了所有选项,但它们都不起作用。我已经评论了每种情况下发生的情况。我不明白它没有找到该文件,因为 bash 文件位于同一目录中。

【问题讨论】:

  • “什么都没有发生”是什么意思?您是否希望将 bash 脚本的输出打印到标准输出?如果是这样,没有更多的代码就不会发生这种情况。
  • 还有一些空间可以进行更多实验。其中一个示例是启动交互式 shell(而不是尝试立即运行脚本),另一个示例是为脚本提供完整路径。
  • 另外,首先您可能希望在该脚本中有一些可以确定工作的内容,例如将某些内容回显到文件中,例如 /tmp/my.test
  • 您的代码不起作用,因为它已全部被注释掉。
  • @Andreas,哈哈。是的,确实是这个问题。

标签: java bash shell ubuntu


【解决方案1】:

您看不到输出有两个原因:

  1. 您无需等待进程完成
  2. 您不会将其输出重定向到您的 Java 进程运行的同一控制台

而且,您可能需要使用/bin/bash -c path/to/your/file.sh 之类的命令。请注意 -c 标志。

恕我直言,用 Java 制作和执行外部进程的最佳方法是 java.lang.ProcessBuilder

假设您在 resources 目录中的某处有您的 sh 文件,这里是一个示例主类:

public class App {
    public static void main(String[] args) throws Exception {
        final ProcessBuilder processBuilder = new ProcessBuilder("/bin/bash", "-c", App.class.getResource("/46964369.sh").getPath());

        processBuilder.redirectInput(Redirect.INHERIT);
        processBuilder.redirectOutput(Redirect.INHERIT);
        processBuilder.redirectError(Redirect.INHERIT);

        processBuilder.start().waitFor();
    }
}

请注意,我使用 redirect* 方法重定向进程的流。 Redirect.INHERIT 将流重定向到 JVM 实例的对应流。它适用于输入和输出流。最后,我正在等待使用waitFor() 方法完成的过程。实际上,您可以做更多的事情,例如将输出捕获到字符串中、从字符串中提供输入或异步运行进程,但这只是一个最小的示例。

如果您将sh 文件存储在其他位置,则必须更新与路径相关的逻辑。

查看完整示例here。这是一个Gradle项目,你可以使用./gradlew run来执行它:

$ ./gradlew run
:compileJava
:processResources
:classes
:run
Hello, world!

BUILD SUCCESSFUL in 4s
3 actionable tasks: 3 executed

【讨论】:

  • 我回家后会试试的。 sh 文件位于程序的目录中。我认为您的代码将非常感谢。如果可行,我会报告。
  • 而且,是的,您也可以为进程指定一个工作目录,这样它就会知道在哪里解析文件。
  • 抱歉花了这么长时间。好吧,我试过那个例子。我用我的文件替换了您示例中的文件。但现在它只是说该文件不存在!它没有隐藏,我完全可以访问它。会是什么?
  • /bin/bash: /home/pi/Documents/Java/BlueJ%20Projects/Trashprojects/shell/send.sh:找不到文件或路径。 (从德语翻译)
  • 我忘了说:我正在用 ubuntu 开发树莓派