只有一行 SimpleHTTPServer 输出没有出现,而 运行 容器没有'-it'
Only one line of SimpleHTTPServer output does not appear while running container without '-it'
注意:我并不是要在这里解决实际项目中的任何问题。这个问题只是为了了解我在下面的第二个实验(实验 2)中看到的结果背后的原因。
这些实验是在 macOS High Sierra 10.13.1 上使用 Docker 版本 17.12.0-ce 在 macOS 终端版本 2.8 上进行的。
实验 1:docker run
具有 -it
个选项的 SimpleHTTPServer
这是我的 Dockerfile
:
FROM python:2.7-slim
CMD ["python", "-m", "SimpleHTTPServer"]
我构建它并 运行 使用此命令:
docker build -t pyhttp .
docker run -it -p 8000:8000 pyhttp
在另一个终端中,我使用以下命令测试容器:
curl http://localhost:8000/
curl
命令产生预期结果:目录列表。在终端 运行ning docker run
中,我看到了这个预期的输出。
$ docker run -it -p 8000:8000 pyhttp
Serving HTTP on 0.0.0.0 port 8000 ...
172.17.0.1 - - [04/Feb/2018 10:07:33] "GET / HTTP/1.1" 200 -
最后,我通过按 Ctrl + C.
停止这个 docker 容器
实验 2:docker run
没有 -it
选项的 SimpleHTTPServer
现在我 运行 使用此命令生成相同的 pyhttp
图像:
docker run -p 8000:8000 pyhttp
即使容器 运行ning 也没有输出出现在终端上。我没有看到预期的 Serving HTTP on 0.0.0.0 port 8000 ...
消息。
尽管如果我使用 curl http://localhost:8000/
测试容器,我会看到 GET
请求的日志出现在终端 运行ning docker run
.
$ docker run -p 8000:8000 pyhttp
172.17.0.1 - - [04/Feb/2018 10:12:41] "GET / HTTP/1.1" 200 -
问题:为什么最初的Serving HTTP on 0.0.0.0 port 8000 ...
消息没有出现,但HTTP请求的后续日志却出现了?
实验 3:docker run
没有 -it
选项的 Flask 应用程序
我构建它并 运行 使用此命令:
docker build -t flaskapp .
docker run -p 8000:8000 flaskapp
在另一个终端中,我使用以下命令测试容器:
curl http://localhost:8000/
在终端 运行ning docker run
中,我看到了这个预期的输出。
$ docker run -p 8000:8000 flaskapp
* Running on http://0.0.0.0:8000/ (Press CTRL+C to quit)
172.17.0.1 - - [04/Feb/2018 10:22:28] "GET / HTTP/1.1" 200 -
问题:为什么只有实验2没有出现Serving HTTP on 0.0.0.0 port 8000 ...
信息?
python -m SimpleHTTPServer
的第一行输出被打印到 stdout
;剩余的行打印到 stderr
。考虑这些调用之间的区别:
njv@organon:~/tmp$ python -m SimpleHTTPServer
Serving HTTP on 0.0.0.0 port 8000 ...
172.17.2.26 - - [06/Feb/2018 20:55:52] "GET / HTTP/1.1" 200 -
njv@organon:~/tmp$ python -m SimpleHTTPServer > /dev/null
172.17.2.26 - - [06/Feb/2018 20:56:26] "GET / HTTP/1.1" 200 -
第二个不显示 "Serving" 行,因为 stdout
被丢弃,但都显示日志行,因为 stderr
不是。另一方面,Flask 将其 "starting" 日志写入 stderr
(以及更多日志行):
njv@organon:~/tmp$ python flaskapp.py > /dev/null
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
127.0.0.1 - - [06/Feb/2018 20:58:10] "GET / HTTP/1.1" 200 -
(从此处编辑)您对 python 的 docker 调用发生的情况是,如果没有 -t
选项,stdout 是完全缓冲的,并且 -t
选项,它是行缓冲的,因此它会在每个换行符之后立即出现。
$ docker help run|grep -- ' -t'
-t, --tty Allocate a pseudo-TTY
我仍在寻找这方面的权威来源(this article 看起来很有希望),但似乎当 sys.stdout.isatty() is True
、python 打开 stdout
时-缓冲模式,所以每一行都显示为打印出来的,但如果没有,它会以完全缓冲模式打开,因此只有在缓冲区已满时才会打印输出。
注意:我并不是要在这里解决实际项目中的任何问题。这个问题只是为了了解我在下面的第二个实验(实验 2)中看到的结果背后的原因。
这些实验是在 macOS High Sierra 10.13.1 上使用 Docker 版本 17.12.0-ce 在 macOS 终端版本 2.8 上进行的。
实验 1:docker run
具有 -it
个选项的 SimpleHTTPServer
这是我的 Dockerfile
:
FROM python:2.7-slim
CMD ["python", "-m", "SimpleHTTPServer"]
我构建它并 运行 使用此命令:
docker build -t pyhttp .
docker run -it -p 8000:8000 pyhttp
在另一个终端中,我使用以下命令测试容器:
curl http://localhost:8000/
curl
命令产生预期结果:目录列表。在终端 运行ning docker run
中,我看到了这个预期的输出。
$ docker run -it -p 8000:8000 pyhttp
Serving HTTP on 0.0.0.0 port 8000 ...
172.17.0.1 - - [04/Feb/2018 10:07:33] "GET / HTTP/1.1" 200 -
最后,我通过按 Ctrl + C.
停止这个 docker 容器实验 2:docker run
没有 -it
选项的 SimpleHTTPServer
现在我 运行 使用此命令生成相同的 pyhttp
图像:
docker run -p 8000:8000 pyhttp
即使容器 运行ning 也没有输出出现在终端上。我没有看到预期的 Serving HTTP on 0.0.0.0 port 8000 ...
消息。
尽管如果我使用 curl http://localhost:8000/
测试容器,我会看到 GET
请求的日志出现在终端 运行ning docker run
.
$ docker run -p 8000:8000 pyhttp
172.17.0.1 - - [04/Feb/2018 10:12:41] "GET / HTTP/1.1" 200 -
问题:为什么最初的Serving HTTP on 0.0.0.0 port 8000 ...
消息没有出现,但HTTP请求的后续日志却出现了?
实验 3:docker run
没有 -it
选项的 Flask 应用程序
我构建它并 运行 使用此命令:
docker build -t flaskapp .
docker run -p 8000:8000 flaskapp
在另一个终端中,我使用以下命令测试容器:
curl http://localhost:8000/
在终端 运行ning docker run
中,我看到了这个预期的输出。
$ docker run -p 8000:8000 flaskapp
* Running on http://0.0.0.0:8000/ (Press CTRL+C to quit)
172.17.0.1 - - [04/Feb/2018 10:22:28] "GET / HTTP/1.1" 200 -
问题:为什么只有实验2没有出现Serving HTTP on 0.0.0.0 port 8000 ...
信息?
python -m SimpleHTTPServer
的第一行输出被打印到 stdout
;剩余的行打印到 stderr
。考虑这些调用之间的区别:
njv@organon:~/tmp$ python -m SimpleHTTPServer
Serving HTTP on 0.0.0.0 port 8000 ...
172.17.2.26 - - [06/Feb/2018 20:55:52] "GET / HTTP/1.1" 200 -
njv@organon:~/tmp$ python -m SimpleHTTPServer > /dev/null
172.17.2.26 - - [06/Feb/2018 20:56:26] "GET / HTTP/1.1" 200 -
第二个不显示 "Serving" 行,因为 stdout
被丢弃,但都显示日志行,因为 stderr
不是。另一方面,Flask 将其 "starting" 日志写入 stderr
(以及更多日志行):
njv@organon:~/tmp$ python flaskapp.py > /dev/null
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
127.0.0.1 - - [06/Feb/2018 20:58:10] "GET / HTTP/1.1" 200 -
(从此处编辑)您对 python 的 docker 调用发生的情况是,如果没有 -t
选项,stdout 是完全缓冲的,并且 -t
选项,它是行缓冲的,因此它会在每个换行符之后立即出现。
$ docker help run|grep -- ' -t'
-t, --tty Allocate a pseudo-TTY
我仍在寻找这方面的权威来源(this article 看起来很有希望),但似乎当 sys.stdout.isatty() is True
、python 打开 stdout
时-缓冲模式,所以每一行都显示为打印出来的,但如果没有,它会以完全缓冲模式打开,因此只有在缓冲区已满时才会打印输出。