【问题标题】:Command not found in container在容器中找不到命令
【发布时间】:2020-08-31 09:00:26
【问题描述】:

在 docker 容器内,我运行一个 python 脚本。我的Dockerfile 如下所示

FROM ubuntu:18.04

WORKDIR /ingestion
COPY /services/bcp /ingestion/services/bcp

RUN mkdir -p /tmp/ingestion && \
    chmod +x /ingestion/bcp-build.sh && \
    /ingestion/bcp-build.sh

ENTRYPOINT ["python3", "-m", "services.bcp"]

bcp-build.sh里面我安装了bcp的linux工具:

apt-get update
apt-get upgrade -y
apt-get install -y curl

curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add - 
curl https://packages.microsoft.com/config/ubuntu/16.04/prod.list | tee /etc/apt/sources.list.d/msprod.list 

apt-get update
ACCEPT_EULA=Y apt-get install -y mssql-tools unixodbc-dev 
echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bash_profile
echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc
source ~/.bash_profile
source ~/.bashrc

要运行容器,我使用docker-compose.yml

version: "3"
services:
    bcp: 
        build: .

python(这里的一段代码示例)如下所示:

import argparse

arg_parser: argparse = argparse. \
   ArgumentParser(
       description="Extract tables to CSV",
       usage="bcp.py [-h] [--database [str]]"
   )
required_args: argparse = arg_parser.add_argument_group("required arguments")
required_args.add_argument("--database", metavar="str", type=str, help="database from where to extract", required=True)

def foo():
   args: argparse = arg_parser.parse_args()
   database = args.database
   print(database)

   # build bcp cmd 
   cmd: str = f"bcp {database}.table out /tmp/ingestion/foo.csv"
   subprocess.run(cmd, shell=True) # execute it via subprocess

foo()

要创建图像并使用它,我运行以下命令,docker-compose up -d --build -t foo。有用。但是,当我尝试执行python 代码时,它无法识别bcp 命令。它说 找不到 bcp 命令。您能否指导一下,如何缓解此问题?

确切的错误消息是“bcp command not found”

有趣的是,当我运行docker run -it --rm --entrypoint bash foo 并执行bcp 时,命令可用。

【问题讨论】:

  • 您能否编辑问题以包含实际导致错误的代码、错误消息的实际文本以及应该导致 bcp 工具的 Dockerfile(或 bcp-build.sh)代码在场吗?
  • 希望更新的版本有所帮助。

标签: python python-3.x docker docker-compose dockerfile


【解决方案1】:

当您在映像中安装软件时,您尝试在 .bashrc 中设置备用路径,但运行 Docker 映像的大多数常见路径从不读取这些点文件。 ENTRYPOINT 的 JSON 数组形式根本不涉及 shell,因此不会读取您向 .bashrc.bash_profile 写入的内容。

source 指令也无效:您是从脚本运行它,因此在bcp-build.sh 脚​​本的末尾设置“过期”的环境变量,在任何情况下都是 Dockerfile RUN指令不会注意到或保留环境中的变化。

如果需要修改镜像中的环境变量,则需要使用 Dockerfile ENV 指令。 (唯一可以改变容器环境的东西是在容器启动时运行的脚本。)

ENV PATH $PATH:/opt/mssql-tools/bin

一般而言,Debian 软件包需要将其软件安装在正常的“系统”目录中,因此您可能会提出一个错误,即该支持工具没有像普通二进制文件那样安装到 /usr/bin

【讨论】:

  • (如果你把ENTRYPOINT改成CMD,你可以docker run --rm foo env检查进程的环境,或者docker run --rm foo which bcp,没有笨拙的--entrypoint选项。还要考虑如果您的脚本的 --database 选项中有 ; 或其他标点符号:subprocess.call(..., shell=True) 是一个重大的安全问题。)
  • 非常感谢!这解决了我的问题!!!非常感谢!不知道source不起作用
猜你喜欢
  • 2017-10-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-25
  • 1970-01-01
相关资源
最近更新 更多