繁体   English   中英

Docker CMD 命令在启动容器时不执行,但在容器内运行时有效

[英]Docker CMD commad does not execute while running starting the container but works when run from within the container

我有一个 python 脚本,它计算给定文件的字数并在执行后将 output 保存到“result.txt”文件。 我希望我的 docker 容器在容器启动时执行此操作并在控制台显示 output。 下面是我的 docker 文件和 python 文件

FROM python:3
RUN mkdir /home/data
RUN mkdir /home/output
RUN touch /home/output/result.txt
WORKDIR /home/code
COPY word_counter.py ./
CMD ["python", "word_counter.py"]
ENTRYPOINT cat ../output/result.txt
import glob
import os
from collections import OrderedDict
import socket
from pathlib import Path

dir_path = os.path.dirname(os.path.realpath(__file__))
# print(type(dir_path))
parent_path = Path(dir_path).parent
data_path = str(parent_path)+"/data"
# print(data_path)
os.chdir(data_path)
myFiles = glob.glob('*.txt')

output = open("../output/result.txt", "w")
output.write("files in home/data are : ")
output.write('\n')
for x in myFiles :
    output.write(x)
    output.write('\n')

output.close()

total_words = 0

for x in myFiles :
    file = open(x, "r")
    data = file.read()
    words = data.split()

    total_words = total_words + len(words)
    file.close()

output = open("../output/result.txt", "a")
output.write("Total number of words in both the files : " + str(total_words))
output.write('\n')
output.close()

frequency = {}
for x in myFiles :
    if x == "IF.txt" :
        curr_file = x

document_text = open(curr_file, 'r')
text_string = document_text.read()
words = text_string.split()
 
for word in words:
    count = frequency.get(word,0)
    frequency[word] = count + 1

frequency_list_desc_order = sorted(frequency, key=frequency.get, reverse=True)

output = open("../output/result.txt", "a")
output.write("Top 3 words in IF.txt are :")
output.write('\n')

ip_addr = socket.gethostbyname(socket.gethostname())

for word in frequency_list_desc_order[:3]:
    line = word + " : " + str(frequency[word])
    output.write(line)
    output.write('\n')

output.write("ip address of the machine : " + ip_addr + "\n")
output.close()

我正在将一个包含两个文本文件 IF.txt 和 Limerick1.txt 的本地目录从主机映射到容器内的目录“/home/data”,容器内的 python 代码读取文件并将 output 保存到结果容器内“home/output”中的 .txt。

当我使用 docker 运行命令启动容器时,我希望我的容器将“result.txt”中的 output 打印到控制台。

问题:docker 在使用 docker run 启动容器时不执行以下语句。

CMD ["python", "word_counter.py"]

运行容器的命令:

docker run -it -v /Users/xyz/Desktop/project/docker:/home/data proj2docker bash

但是当我从容器中运行相同的命令“python word_counter.py”时,它执行得非常好。

有人可以帮我弄这个吗?

您的 Dockerfile 中有一个入口点。该入口点将运行并基本上将CMD作为附加参数。

启动容器时运行的最终命令如下所示

cat ../output/result.txt python word_counter.py

这可能不是您想要的。 我建议删除该入口点。 或者根据您的需要进行修复。

如果您想打印该文件并仍然执行该命令,您可以执行如下操作。

CMD ["python", "word_counter.py"]
ENTRYPOINT ["/bin/sh", "-c", "cat ../output/result.txt; exec $@"]

它将运行一些命令作为入口点,在本例中打印该文件的 output,然后执行 CMD,它以$@的形式作为其标准 posix shell 行为。 在任何 shell 脚本中,访问传递给脚本的所有 arguments 的工作方式都是一样的。 这里使用exec的好处是它会运行进程id为1的python,当你想向容器中的python进程发送信号时很有用,例如kill。

最后,当您使用显示的命令启动容器时

docker run -it -v /Users/xyz/Desktop/project/docker:/home/data proj2docker bash

您正在覆盖 Dockerfile 中的 CMD。因此在这种情况下,预计它不会运行 python。即使您的入口点没有前面提到的问题。 如果你想始终运行 python 程序,那么你需要将那部分作为入口点。 您会遇到的问题是,它会先运行入口点,直到完成,然后再运行您的命令,在本例中为 bash。

如果需要,您可以在后台运行它。 请注意,没有默认的 CMD,但 exec $@仍然允许您运行任意命令,例如 bash,而 python 在后台运行。

ENTRYPOINT ["/bin/sh", "-c", "cat ../output/result.txt; python word_counter.py &; exec $@"]

如果您在入口点做了很多工作,将其移至专用脚本并将该脚本作为入口点运行可能更清晰,您仍然可以在 shell 脚本的末尾调用 exec $@。

根据您的评论,您想先运行 python,然后再对文件执行 cat。 您可以删除入口点并仅使用命令执行此操作。

CMD ["/bin/sh", "-c", "python word_counter.py && cat ../output/result.txt"]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM