运行 后台进程与 运行 后台管道
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
运行宁
- 把上面两个文件放到一个文件夹里
- 使用
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 命令也会忽略日志文件中的其他条目。
顺便说一句:我欢迎使用 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
我想从 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
运行宁
- 把上面两个文件放到一个文件夹里
- 使用
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 命令也会忽略日志文件中的其他条目。
顺便说一句:我欢迎使用 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