我正在尝试输出导入.sqlmariadb docker容器中的文件。
我有以下文件/目录设置:
│- docker-compose.yml
│- Dockerfile
│- import.sh
└── sql
- test.sql (rather big: ~ 1GB)我的docker-compose.yml就像..。
services:
db:
build: ./
environment:
MYSQL_ROOT_PASSWORD: root
volumes:
- ./:/docker-entrypoint-initdb.d使用...with命令安装以下Dockerfile文件pv(管道查看器)。
pv应该会给我进度条显示当前导入的距离...
FROM mariadb
RUN apt-get update && apt-get install -y pvThe The The import.sh中的映射卷执行/docker-entrypoint-initdb.d如下所述..。
#!/bin/bash
# create db
mysql -uroot -proot <<-EOF
CREATE DATABASE test;
EOF
# import sql file and output progress with pv
echo "importing test.sql..."
pv --force "/docker-entrypoint-initdb.d/sql/test.sql" | mysql -uroot -proot "test"现在,如果我运行docker-compose up它100%仅输出
导入结束时的pv输出
importing test.sql...
953MiB 0:01:24 [11.2MiB/s] [================================>] 100% 0:05:42如果我执行相同的命令内部它工作的容器,它给了我一个移动的进度条:
pv --force "/docker-entrypoint-initdb.d/sql/test.sql" | mysql -uroot -proot "test"
60.4MiB 0:00:14 [5.79MiB/s] [=> ] 6% 0:04:53如何打开此进度条docker-compose up而不是长时间等待和100%输出?
发布于 2021-02-24 22:27:12
背景
首先,让我们了解一下pv能够在终端的纯文本输出上呈现移动的进度条: pv实际上,在每次进度更新时,只是将纯文本打印到其stdout:
"[==> ] 25%\r"
"[======> ] 50%\r"
"[=========> ] 76%\r"
"[============>] 100%\n"此处的每一行都表示一个进度更新,pv输出文本在引号(所以没有引号)。
但这不会以多行的形式打印到终端:\r是一个回车用于将光标移回行首的字符在不开始新行的情况下..。因此,下一个进度输出将覆盖生成进度条动画的上一个文本。
仅在上次更新之后pv将打印换行符\n导致输出后的最后一个换行符。
现在来看看下面的问题docker-compose:使用启动应用程序docker-compose up将启动所有服务,附加到它们的输出,并将其记录到自己的输出中-以各自的服务名称为前缀:
app_1 | starting App...
db_1 | initializing database
....要做到这一点docker-compose
将读取每个容器中的每个输出行,并在打印之前为其添加服务名称前缀。
但正如我们之前看到的pv实际上只打印一行!这就是为什么docker-compose在最终打印输出之前,将一直缓冲到输出的末尾!
解决方案
我在这里看到了两种可能的解决方案:
使用docker-compose run db初始化数据库:这将运行容器,并将其输出直接附加到控制台,并打印输出,而不进行任何缓冲或后处理。
在这种情况下,您甚至可以省略--force旗帜。
替换\r使用\n强制将每个进度更新打印在新行上,例如使用 tr..。此外,要确保禁用您可以使用的任何输出缓冲 stdbuf使用它(请参见关闭管道中的缓冲turn off buffering in pipe):
(pv --force -p "/docker-entrypoint-initdb.d/sql/test.sql" | mysql -uroot -proot "test") 2>&1 | stdbuf -o0 tr '\r' '\n'将记录
db_1 | [==> ] 25%
db_1 | [======> ] 50%
db_1 | [=========> ] 76%
db_1 | [============>] 100%演示
下面是上面的一个小演示:
# Dockerfile
FROM alpine
RUN apk add pv# docker-compose.yml
services:
app:
build: .
command: sh -c "pv --force -p -Ss 1024 -L 100 /dev/urandom 2>&1 > /dev/null | tr '\r' '\n'"附录
根据评论,上面的演示不能与基于ubuntu的图像一起工作。它似乎在这样的图像中tr将缓冲其输出,并仅在退出时打印所有内容。
但是,可以使用以下命令禁用输出缓冲区stdbuf(另请参阅
关闭管道中的缓冲turn off buffering in pipe):
# Dockerfile
FROM ubuntu
RUN apt-get update && apt-get install -y pv# docker-compose.yml
services:
app:
build: .
command: sh -c "pv --force -p -Ss 1024 -L 100 /dev/urandom 2>&1 > /dev/null | stdbuf -o0 tr '\r' '\n'"发布于 2021-02-24 18:09:03
我找到了一个比较好的解决方案:
添加--numeric 将标志发送到我的pv命令。
从pv的手册页
-n,--数字
数字输出。pv将给出一个整数百分比,每行一个,而不是给出进度的可视指示。
,在标准错误上,适用于管道(通过卷积重定向)进入对话(1)。请注意,如果使用-n,则不需要-f。
所以我的命令import.sh将是:
pv --numeric "/docker-entrypoint-initdb.d/sql/test.sql" | mysql -uroot -proot "test"这将给出以下输出:
importing test.sql...
36
53
80
100由于这不如pv这个答案并不完美...
我还尝试了一些更好的输出,但没有换行符,比如:
importing test.sql...
36% 53% 80% 100%使用附加的 awk命令:
(pv --numeric "/docker-entrypoint-initdb.d/sql/test.sql" | mysql -uroot -proot "test") 2>&1 | awk '{printf "%s% ",$0}'但是,同样的问题:这只起作用内部容器,而不是docker-compose up..。
https://stackoverflow.com/questions/66329515
复制相似问题