Docker CMD commad在启动容器时不执行,但在容器内运行时起作用

2024-05-19 21:14:51 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个python脚本,它计算给定文件的字数,并在执行后将输出保存到“result.txt”文件中。我希望docker容器在容器启动时执行此操作,并在控制台上显示输出。下面是我的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代码读取文件并将输出保存到容器内“home/output”中的result.txt

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

问题: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”时,它执行得非常好

有人能帮我吗


1条回答
网友
1楼 · 发布于 2024-05-19 21:14:51

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

启动容器时运行的最后一个命令如下所示

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

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

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

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

它将运行一些命令作为入口点,在本例中打印该文件的输出,然后执行CMD,作为其标准posix shell行为$@。在任何shell脚本中,访问传递给脚本的所有参数都是一样的。这里使用exec的好处是,它将运行进程id为1的python,这在您希望将信号发送到容器中到python进程(例如kill)时非常有用

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

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

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

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

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

如果您在entrypoint中做了大量工作,那么将其移动到专用脚本并作为entrypoint运行该脚本可能会更干净,您仍然可以在shell脚本的末尾调用exec$@

根据您的评论,您希望先运行python,然后在文件上运行cat。您可以删除入口点,只需使用命令即可

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

相关问题 更多 >