bash - 将当前目录中的文件名列表作为单个字符串发送到 Docker 容器的 STDIN

标签 bash docker shell zsh stdin

我有一个 Docker 容器,需要传递一个包含当前目录中文件名的字符串(字符串数组也可以,但据我所知这是不可能的)。
我获取容器内文件名的第一个策略是运行命令 docker build -t doc-validate . && docker run doc-validate (printf "%s " $(ls -p | grep -v /)) , 发送 (printf "%s " $(ls -p | grep -v /)) 的输出直接进入容器的标准输入,但是,我得到 zsh: bad pattern: (printf %s Dockerfile作为错误返回;在我看来,容器或 shell 试图在某处执行“Dockerfile”,但我不知道为什么会发生这种情况,因为运行相同的 printf命令直接在终端中按预期工作(仅打印当前目录中的文件名)。
我的第二种方法是尝试将这些文件名作为环境变量发送到容器。运行 PROJECT_FILES=(printf "%s " $(ls -p | grep -v /))在终端中按预期工作,$PROJECT_FILES输出这些文件名。但是,如果我尝试像这样将其直接传递到容器中:docker build -t doc-validate . && docker run --env PROJECT_FILES=(printf "%s " $(ls -p | grep -v /)) doc-validate我得到同样的 zsh: bad pattern: PROJECT_FILES=(printf %s Dockerfile作为错误。
在我看来,由于 'zsh:' 在错误输出中,命令甚至在进入容器之前就失败了,但是,我不明白为什么在终端中独立运行它们以及为什么将它们作为参数传递给容器真是头疼。
如何获得运行 (printf "%s " $(ls -p | grep -v /)) 的输出在我的本地机器中作为容器内可访问的值?
Dockerfile:

FROM node:16
WORKDIR /moduleRoot
COPY package.json /moduleRoot
RUN npm install
COPY . /moduleRoot/
# Authorize execution of entrypoint bash script
RUN chmod +x /moduleRoot/docker-container-entrypoint.sh
# these values below will be set later, just register them explicitly here
ENV PROJECT_FILES=""
CMD [ "/moduleRoot/docker-container-entrypoint.sh" ]
Bash 入口点(CMD 中的 docker-container-entrypoint.sh 文件):
#!/bin/bash
echo "Args are: $@"
echo "PROJECT_FILES=$PROJECT_FILES"

最佳答案

首先是您正在使用 node:16并根据 entrypoint该项目将调用 node执行您作为参数传递的任何内容。
在您的 Dockerfile您正在调用 CMD并且不改变 ENTRYPOINT ,所以当你执行容器时,它会尝试使用 node 执行 bash 脚本,你一定会收到这样的错误:

/moduleRoot/docker-container-entrypoint.sh:2
echo "Args are: $@"
     ^^^^^^^^^^^^^^

SyntaxError: Unexpected string
    at Object.compileFunction (node:vm:353:18)
    at wrapSafe (node:internal/modules/cjs/loader:1039:15)
    at Module._compile (node:internal/modules/cjs/loader:1073:27)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1138:10)
    at Module.load (node:internal/modules/cjs/loader:989:32)
    at Function.Module._load (node:internal/modules/cjs/loader:829:14)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:76:12)
    at node:internal/main/run_main_module:17:47
如果您的 bash 脚本只是为了帮助您排除故障,那么您可以使用在线 heredoc传递你需要的参数:
» docker run -t --rm doc-validate <<< echo $(ls -a1)

Args are: docker-container-entrypoint.sh Dockerfile package.json
PROJECT_FILES=
另一方面,如果您需要 bash 脚本,则必须更改 CMDENTRYPOINT .另外值得注意的是Linux的ls没有 -p旗帜。

关于bash - 将当前目录中的文件名列表作为单个字符串发送到 Docker 容器的 STDIN,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68040159/

相关文章:

linux - 将两个特定的 Linux 命令合并为一个

linux - 获取从开始索引到结束索引的子字符串

java - 在 Ubuntu WSL 中运行 bash 脚本时出现不一致的 S3 参数验证错误

如果命令行输出不包含字符串,则发送邮件的 Bash 脚本

linux - grep 匹配后的词 + 制表符

bash - 在Docker中编写脚本文件有什么优势?

docker - 当 Docker 桌面在 WSL2 中运行时,bash 中的长工作目录

nginx - 如何使用 Docker Compose 启动 2 个(或更多)Rocket.Chat 实例?

c - 如何使用 GNU Readline 处理 Ctrl+D

linux - Linux 中的并发