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

How to run docker commands or shell scripts with docker commands from Java application

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

没有任何内容被打印到 eclipse IDE 控制台,尽管当我修改 .sh 文件以执行 echo 'i am responding' 它被打印到控制台。为了调试代码,我修改了 .sh 脚本以将 docker 拉取的 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();
    }

}

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

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 安装而缺少权限。我不知道你用的是哪个OS,假设是Linux,考虑看看Post-Linux的安装步骤:https://docs.docker.com/engine/install/linux-postinstall/

答案是“第 11 行:docker:找不到命令”:)

当启动一个终端时,你正在启动一个 shell,它的路径可能设置在类似 .bashrc 的东西中(或者你 shell 的任何 rc 文件 运行宁).

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

验证这一点:

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

修复它:

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