python - Docker CMD commad 在运行启动容器时不执行,但在从容器内运行时工作
问题描述
我有一个 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 代码读取文件并将输出保存到结果.txt 在容器内的“home/output”中。
当我使用 docker run 命令启动容器时,我希望我的容器将“result.txt”中的输出打印到控制台。
问题:使用 docker run 启动容器时,docker 不执行以下语句。
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 $@"]
它将运行一些命令作为入口点,在这种情况下打印该文件的输出,然后执行可$@
作为其标准 posix shell 行为的 CMD。在任何 shell 脚本中,访问传递给脚本的所有参数都是一样的。在这里使用 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 $@
,它允许您在 python 在后台运行时运行任意命令,例如 bash。
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"]
推荐阅读
- architecture - 根据 Clean Architecture,SNS 上不存在实体且仅存在用例?
- highcharts - 如何使 Highcharts 中饼图的连接器(连接数据标签的线)看起来是直线而不是弯曲的?
- angular - Azure 应用服务中的 Dotnet 发布错误 - 错误:找不到模块“@angular/core”
- babeljs - 如何在非nodejs环境/没有npm的情况下配置babel?
- unix - 仅从 csv 文件中获取重复项
- python - CNN 多输入,检查模型输入时出错:预计会看到 2 个数组,但得到了以下 1 个数组的列表:
- sql - 与 Oracle 部分匹配
- ios - 如何使可点击的 NSAttributedString 移动到另一个 ViewController Swift
- android - 如何以编程方式按 dialPad btn?
- java - 如何在 java CollectionUtils.class addAll 方法中分析“更改 |= collection.add(iterator.next()”?