如何使用来自 Java 应用程序的 docker 命令运行 docker 命令或 shell 脚本

时间:2021-02-17 20:12:46

标签: java docker processbuilder

我需要从 Java 应用程序运行一些 docker 命令。到目前为止,我已经搜索并尝试了运行时 exec 和 processBuilder 方法,但它不起作用。我的最后一次尝试是使用 processBuilder 尝试执行包含 docker pull 命令的 bash 脚本。

eclipse IDE 控制台没有打印任何内容,尽管当我修改 .sh 文件以执行 echo 'i am responding' 时,它已打印到控制台。为了调试代码,我修改了 .sh 脚本以将 docker pull 的 stdout 和 stderr 重定向到一个文件。打开生成的文件后,我得到: line 11: docker: command not found 而当我在终端中运行它时,docker 命令工作正常。因此我假设问题出在 java 代码本身。我哪里错了?。任何帮助将不胜感激。

注意:我也听说过并尝试过 Spotify docker-client 库,但我想我目前对 Docker 的了解还不足以进行设置。 我正在使用 MacOS Big Sur。这是java代码:

public static void main(String[] args) throws IOException {
    Common cm = new Common();
    String userDir = cm.getuserDirectory();
    String sp = cm.getfileSeparator();
    String filePath = userDir + sp + "src" + sp +  "data" + sp + "pull-and-run.sh";
    
    String[] cmd = {"sh", filePath};
    
    ProcessBuilder processBuilder = new ProcessBuilder(cmd);
    processBuilder.directory(new File(userDir + sp + "src" + sp +  "data"));
    
    Process process;
    
    try {
        process = processBuilder.start();
        BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
        
        String line;

        System.out.println("Output is: ");
        while ((line = br.readLine()) != null) {
            System.out.println(line);
        }
        
    } catch (IOException e) {
        e.printStackTrace();
    }

}

2 个答案:

答案 0 :(得分:0)

我尝试使用您的代码的简化版本进行重现,创建一个带有 Main 类和 show-docker-version.sh 文件(在项目的根目录中)的简单 java 项目:

show-docker-version.sh

docker --version

Main.java

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {

        String filePath = "docker-container-list.sh";
        String[] cmd = {"sh", filePath};
        ProcessBuilder processBuilder = new ProcessBuilder(cmd);
        processBuilder.directory(new File("."));
        Process process;
        try {
            process = processBuilder.start();
            BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));

            String line;

            System.out.println("Output is: ");
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }

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

输出为:

Output is: 
Docker version 20.10.3, build 48d30b5

Process finished with exit code 0

所以 docker 命令在这里起作用了!

我至少尝试过两种不同的 JDK(8 和 11),但不是全部。所以我想知道是否与您的JDK版本有关。另一种可能是由于 docker 安装导致权限不足。不知道你用的是哪个操作系统,假设是Linux,考虑看看Linux的安装后步骤:https://docs.docker.com/engine/install/linux-postinstall/

答案 1 :(得分:0)

答案是“第 11 行:docker: command not found”:)

启动终端时,您正在启动一个 shell,它的 PATH 可能设置在 .bashrc 之类的文件中(或您正在运行的任何 shell 的 rc 文件)。

我知道您是从 Eclipse 中启动应用程序的,而且您可能从桌面、菜单或应用程序启动器启动 Eclipse:所有这些都没有您的终端所具有的设置。

验证:

  • 从终端运行您的应用程序,而不是从 Eclipse 中运行 或
  • 在您从应用程序中启动的脚本中添加“echo $PATH”行,并将其与终端中运行的 echo $PATH 进行比较。

修复:

  • 将 docker 添加到桌面会话使用的“全局”PATH 或
  • 在脚本中提供docker的完整路径 或
  • 从终端内启动 eclipse;它将继承shell的环境
相关问题