我有一个像这样的简单 Dockerfile
FROM ubuntu:latest
ADD run.sh /run.sh
CMD /run.sh
在 run.sh 中,我有这个(也非常简单)
#!/bin/bash
nohup awk 'BEGIN { while (c++<50) print "y" }' &
sleep 10
当我从 bash 在 docker 中运行脚本时(即,在交互模式下运行 bash 命令并运行脚本),它工作正常 - 它进入“nohup 模式”并且输出正确地在 nohup.out 中。
但是,如果我使用默认命令运行 docker 容器/run.sh
,输出仍然在 STDOUT 中。
我究竟做错了什么?为什么它在 docker、bash 中都可以工作,但只有在交互模式下运行时才能工作?
答案1
nohup
仅当命令的输出发送至终端时才重定向该命令的输出。如果输出已经转到另一种类型的文件(例如常规文件或管道),nohup
则假定这是所需的并且不会重定向到nohup.out
.
默认情况下,docker run
通过套接字运行命令(将主机与虚拟环境连接——这就是它们通信的方式)。套接字不是终端,因此nohup
不执行任何重定向。
如果运行docker run -t
,Docker 将模拟容器中的终端,因此nohup
将重定向到nohup.out
.如果您不传递命令名称,那么 docker 的行为就像您使用了docker run -t bash
.
最好的解决方案是将命令的输出显式重定向到您选择的日志文件。不要忘记重定向 stderr。这样你就会知道他们要去哪里。
nohup awk 'BEGIN { while (c++<50) print "y" }' >myscript.log 2>&1 &
答案2
我对 Docker 了解不多,但是nohup
它具有一些内在的魔力关于命令输出的重定向。它根据位置将其引导到不同的地方它自己的输出被指出。
有关更多详细信息,请参阅链接的答案 - 您会在其中找到确切的答案,并且POSIX 规范nohup
。