◐ Shell
clean mode source ↗

(新手向)记录一下docker exec遇到的一些问题等,OCI STDOUT: OCI runtime exec failed: exec failed: unable to start container process: exec: "sh -c \"ls\"": executable file not found in $PATH: unknown · docker-java/docker-java · Discussion #2325

可能会有国外的朋友不好ocr识别翻译,我贴一下原文吧,翻译就机翻了。

        String cmd = new String(Files.readAllBytes(Paths.get("E:/bishe/cmd.txt")), StandardCharsets.UTF_8);
        /**
         * 纪念一下这里,这个bug修了我24h+
         * 这个withCmd方法你也真有够逆天的,必须传一个String数组。
         * 因为docker-java底层走的是docker remote API,和我们平时docker exec走的docker-cli完全是两个东西
         * 这个execCreate底层是发post请求的,entryPoint和arguments是作json键值对发给docker的,
         * 和我们平时命令行看起来就是一串带空格的String完全不一样,毕竟json是字典格式
         * 这逆天withCmd方法会固定把数组[0]作为entryPoint,[0]之后每一个成员作为一项argument,
         * 用inspectExec查一下准备好的exec把他的config打印出来就能看的很清楚
         * 每一项String数组都会作为json那里arguments列表的一个成员,String内有空格也不要加引号,反而弄巧成拙,
         * 会报OCI的错,不识别命令,你这引号一引起来反而成了字符串。
         * 说到底就是docker remote API和docker-cli分割命令、参数的方式不同,前者是数组成员,后者是空格
         */
        String execId = dockerClient.execCreateCmd(map.getString("env-name"))
                .withAttachStdin(true).withAttachStderr(true).withAttachStdout(true)
                .withCmd("sh", "-c", cmd).withPrivileged(true).withContainerId(containerId).exec().getId();
        InspectExecResponse r = dockerClient.inspectExecCmd(execId).exec();
        System.out.println(r.getProcessConfig());