2

I am trying to build docker with simple python script the read from a file and print it.
I want that the python script will continue to read from the file as new data may be available in the file.
But when the file does not exist when the scripts start it seems that tail does not work and does not read the file.
Here is simple example:

dockerfile (uncomment to illustrate the problem)

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)

If I enter to the docker (when there is no /tmp/file) and start to write to that file (using echo "text" >> /tmp/file) I can see the output in the docker screen.
But if I uncomment the touch comment in the dockerfile (that cause /tmp/file to be created) I can not see any output in the docker screen although I use the same command(echo "text" >> /tmp/file).
Why there is such a diffrent and how I can see the output even if the file exists?

-- edit --
I have tried to add exit(1) after the first read line to negate buffer problem.
The result was pretty much the same:
When the line was commant the container exit as expected (with exit code 1)
but when the line was uncommant the container does not exit at all (probably stuck on reading from the pipe).
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)

-- edit 2 --
The problem happen also if there is only the docker file:
dockerfile

FROM ubuntu:18.10
#RUN touch /tmp/file
CMD "tail" "-c-1" "-F" "/tmp/file"
amit
  • 177
  • 1
  • 13
  • It is interesting and maybe my problem but the difference is that I run tail with -F and in this question the tail run with -f. – amit Mar 17 '19 at 19:27

2 Answers2

0

It's known behavior, this problem related to zero size file, and if you will try to use simple tail -f in the container, you will see the same behavior. The same topic explains why.

This option, that zero file exists is synthetic, in real life real streams creates files with content, so this is why this question is not so popular across the Internet.

As mentioned in topic, you need to verify that file exists and size is not zero.

Dmitrii
  • 877
  • 1
  • 6
  • 12
0

Try with sys.stdout.flush() after print, to force output buffer being printed on the screen too. It seems to work for me (same dockerfile and script)

jgoday
  • 2,768
  • 1
  • 18
  • 17
  • Have you tried to uncomment the touch command in the docker file? The problem happen only if there is already a file. – amit Mar 16 '19 at 09:06
  • Yes, i tested with your dockerfile (https://pastebin.com/DF28GcBN) and this main.py (https://pastebin.com/g3F884vd) – jgoday Mar 16 '19 at 09:37
  • I tried to do as you suggested but same result. I can not see any output from the container. – amit Mar 16 '19 at 09:47
  • Anyway I have added example without print,so unfortunately is not the buffer. :( – amit Mar 16 '19 at 10:03