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

时间:2020-12-30 11:03:47

标签: docker sh pipeline

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

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

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

Dockerfile

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

运行

  • 将上面的两个文件放到一个文件夹中。
  • 使用 docker build --tag pipeline .
  • 构建映像
  • 在一个终端中使用 docker run --init --rm --name pipeline pipeline 运行图像。您还可以在此处查看容器的输出。
  • 在第二个终端中,用 docker exec -it pipeline bash 打开一个 shell,然后在那里运行,例如date >> /var/log/my-log。您还可以在此处运行这两个 tail ... 命令,以查看它们应该如何工作。
  • 要停止容器,请使用 docker kill pipeline

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

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

1 个答案:

答案 0 :(得分:3)

根据我的测试,似乎 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

相关问题