pipe管道与重定向操作在docker run命令中无法生效的问题咨询
原因说明
你给出的命令中app > app.log是在容器内部的shell进程中执行的,默认生成的app.log存储在容器的临时读写层中:如果执行结束后容器退出且未做目录挂载,该文件不会同步到宿主机,你自然无法在宿主机找到对应文件。此外如果目标应用将输出打印到stderr而非stdout,也会导致stdout重定向不生效。
可用解决方案
方案1:将重定向逻辑放在docker命令外侧,直接输出到宿主机文件
这是逻辑最简单的方案,不需要修改容器内部逻辑,直接捕获docker进程的标准输出写入宿主机文件:
cat path/file1 | docker run -i --name my-container my-image bash -c 'app' > ./app.log
如果需要同时捕获stderr的输出,调整为:
cat path/file1 | docker run -i --name my-container my-image bash -c 'app' > ./app.log 2>&1
方案2:挂载宿主机目录到容器,直接持久化容器内生成的日志
如果需要让应用在容器内部直接写入持久化存储,可以通过-v参数挂载宿主机目录到容器中:
# 提前在宿主机创建存储日志的目录 mkdir -p ./docker_logs cat path/file1 | docker run -i -v "$(pwd)/docker_logs:/data" --name my-container my-image bash -c 'app > /data/app.log'
执行完成后直接到宿主机的./docker_logs目录下即可拿到app.log文件。
方案3:从已执行完成的容器中提取日志
如果你已经用原始命令执行过任务,容器尚未删除,可以直接将容器内的日志文件拷贝到宿主机:
# 请将容器内的日志路径替换为你实际写入的路径,原始命令中默认是/app.log docker cp my-container:/app.log ./app.log
额外注意事项
如果应用存在输出缓冲导致内容没有及时写入文件的问题,可以给容器内的bash加上-u参数关闭缓冲:
cat path/file1 | docker run -i --name my-container my-image bash -uc 'app > app.log'
内容的提问来源于stack exchange,提问作者Jeff Pal
相关产品推荐
相关产品推荐

