我正在尝试使用简单的python脚本构建docker,然后从文件中读取并打印它。
我希望python脚本能继续从文件中读取,因为文件中可能有新数据。
但是当脚本启动时文件不存在时,tail似乎不起作用并且无法读取该文件。
这是简单的示例:
dockerfile (取消注释以说明问题)
FROM ubuntu:18.10
RUN apt-get update && apt-get install -y --no-install-recommends python3 && rm -rf /var/lib/apt/lists/*
#RUN touch /tmp/file # uncomment will cause the problem
COPY . /app/
CMD ["python3","/app/main.py"]
main.py
import subprocess
argsList = ['tail', '-c-1', '-F', '/tmp/file']
f = subprocess.Popen(argsList, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
line = f.stdout.readline()
while line != b'':
line = f.stdout.readline().decode("utf-8")
print(line)
如果我进入docker(没有 / tmp / file时)并开始写入该文件(使用echo“ text” >> / tmp / file),则我可以在docker屏幕中查看输出。
但是,如果我在泊坞窗文件中取消注释触摸注释(这会导致创建/ tmp / file),尽管我使用相同的命令,但我无法在泊坞窗中看到任何输出命令(回显“文本” >> / tmp / file)。
为什么会有这样的差异?即使文件存在,我怎么也能看到输出?
-编辑-
我试图在第一行读取后添加exit(1)来消除缓冲区问题。
结果几乎相同:
当该行是命令行时,容器按预期方式退出(退出代码为1)
但是当该行中断时,容器根本不会退出(可能停留在从管道读取的位置)。
main.py
import subprocess
argsList = ['tail', '-c-1', '-F', '/tmp/file']
f = subprocess.Popen(argsList, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
line = f.stdout.readline()
exit(1)
-编辑2-
如果只有docker文件,也会发生此问题:
dockerfile
FROM ubuntu:18.10
#RUN touch /tmp/file
CMD "tail" "-c-1" "-F" "/tmp/file"
答案 0 :(得分:0)
这是已知的行为,此问题与文件大小为零有关,如果您尝试在容器中使用简单的tail -f
,则会看到相同的行为。相同的topic解释了原因。
该选项(存在零个文件)是合成的,在现实生活中,实际流会创建包含内容的文件,因此这就是为什么这个问题在Internet上没有那么流行的原因。
如主题所述,您需要验证文件是否存在且大小不为零。
答案 1 :(得分:0)
打印后尝试使用sys.stdout.flush(),以强制在屏幕上打印输出缓冲区。它似乎对我有用(相同的dockerfile和脚本)