运行 后台进程与 运行 后台管道

Running a background process versus running a pipeline in the background

我想从 Docker 容器输出一个日志文件,但偶然发现了一些我不明白的东西。这两行不会失败,但只有第一行可以正常工作:

tail --follow "/var/log/my-log" &
tail --follow "/var/log/my-log" | sed -e 's/^/prefix:/' &

检查 运行ning 容器内部,我看到进程是 运行ning 但我只看到容器输出中第一行的输出。

Docker文件

FROM debian:buster-slim

COPY boot.sh /

ENTRYPOINT [ "/boot.sh" ]

boot.sh

必须可执行 (chmod +x)!

#!/bin/sh

echo "starting"

echo "start" > "/var/log/my-log"
tail --follow "/var/log/my-log" &
tail --follow "/var/log/my-log" | sed -e 's/^/prefix:/' &

echo "sleeping"

sleep inf

运行宁

我希望在容器的输出中找到两个 tail ... 命令的输出,但它在日志文件的初始“启动”条目上已经失败了。添加前缀的 tail 命令也会忽略日志文件中的其他条目。

顺便说一句:我欢迎使用 pipes/FIFOs 的解决方法,它可以避免一开始就写入持久日志文件。我仍然想了解为什么会失败。 ;)

根据我的测试,sed 似乎导致了此命令的输出 tail --follow "/var/log/my-log" | sed -e 's/^/prefix:/' & 在 运行 容器时不出现的问题。这个问题可以通过将 -u 传递给 sed 来解决,这会禁用缓冲。

最终的工作boot.sh如下:

#!/bin/sh

echo "starting"

echo "start" > "/var/log/my-log"
tail --follow "/var/log/my-log" &
tail --follow "/var/log/my-log" | sed -u -e 's/^/prefix:/' &

echo "sleeping"
sleep inf

并且 运行 容器后的输出将是:

starting
sleeping
start
prefix:start

将更多数据附加到日志文件也会按预期显示。

starting
sleeping
start
prefix:start
newlog
prefix:newlog

另见:why cant I redirect the output from sed to a file