Linux dd实用程序在sh和bash的同一命令下输出不同的行,如何强制输出docker容器内的最后一行?
在docker容器中,我测试Linux dd实用程序在sh和bash的同一命令下输出不同的行,如何强制输出docker容器内的最后一行?,linux,bash,shell,docker,dd,Linux,Bash,Shell,Docker,Dd,在docker容器中,我测试 ddif=/dev/zero of=/tmp/test2.img bs=512 count=1000 2>>(grep复制) 行执行。我用两种方法钻入容器 1) 经典的是docker exec-it 2b65c84ddce2/bin/sh 这句话是从阿尔卑斯山传来的,我在打招呼 /bin/sh:语法错误:意外重定向,因为附近有东西( 2) 当我将容器输入bash执行器时,比如docker exec-it 2b65c84ddce2/bin/bash ddif=/dev
ddif=/dev/zero of=/tmp/test2.img bs=512 count=1000 2>>(grep复制)
行执行。我用两种方法钻入容器
1) 经典的是docker exec-it 2b65c84ddce2/bin/sh
这句话是从阿尔卑斯山传来的,我在打招呼
/bin/sh:语法错误:意外重定向
,因为附近有东西(
2) 当我将容器输入bash执行器时,比如docker exec-it 2b65c84ddce2/bin/bash
ddif=/dev/zero of=/tmp/test2.img bs=512 count=1000 2>>(grep复制)
不返回任何输出
dd if=/dev/zero of=/tmp/test2.img bs=512 count=1000
仅返回2行输出,而期望值为3:
1+0 records in
1+0 records out
在主机级别,相同的dd
命令返回如下3行:
dd if=/dev/zero of=/tmp/test2.img bs=512 count=1000
1000+0 records in
1000+0 records out
512000 bytes (512 kB, 500 KiB) copied, 0.0109968 s, 46.6 MB/s
通过重定向,输出是最后一行:
dd if=/dev/zero of=/tmp/test2.img bs=512 count=1000 2> >( grep copied )
512000 bytes (512 kB, 500 KiB) copied, 0.0076261 s, 67.1 MB/s
那么如何从docker容器内部获取dd
输出的最后一行呢
附言
将stderr重定向到stdout通常没有帮助:
/ # dd if=/dev/zero of=/tmp/test2.img bs=512 count=1000 2>&1 | grep copied
/ # dd if=/dev/zero of=/tmp/test2.img bs=512 count=1000 2>&1
1000+0 records in
1000+0 records out
在主机系统中,它可以工作
$ dd if=/dev/zero of=/tmp/test2.img bs=512 count=1000 2>&1 | grep copied
512000 bytes (512 kB, 500 KiB) copied, 0.00896706 s, 57.1 MB/s
主持人:
dd --v
dd (coreutils) 8.30
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
事实上,对于搜索此问题的任何人来说,它们都是不同的: 使用的DD与BusyBox一起使用。第三行是可选输出,在从源代码编译BusyBox时定义。预编译版本已禁用此功能 必须定义第三条启用功能状态行 见第166行
#if ENABLE_FEATURE_DD_THIRD_STATUS_LINE
# if ENABLE_FEATURE_DD_STATUS
if (G.flags & FLAG_STATUS_NOXFER) /* status=noxfer active? */
return;
//TODO: should status=none make dd stop reacting to USR1 entirely?
//So far we react to it (we print the stats),
//status=none only suppresses final, non-USR1 generated status message.
# endif
fprintf(stderr, "%llu bytes (%sB) copied, ",
G.total_bytes,
/* show fractional digit, use suffixes */
make_human_readable_str(G.total_bytes, 1, 0)
);
/* Corner cases:
* ./busybox dd </dev/null >/dev/null
* ./busybox dd bs=1M count=2000 </dev/zero >/dev/null
* (echo DONE) | ./busybox dd >/dev/null
* (sleep 1; echo DONE) | ./busybox dd >/dev/null
*/
seconds = (now_us - G.begin_time_us) / 1000000.0;
bytes_sec = G.total_bytes / seconds;
fprintf(stderr, "%f seconds, %sB/s\n",
seconds,
/* show fractional digit, use suffixes */
make_human_readable_str(bytes_sec, 1, 0)
);
#endif
}
\if ENABLE\u FEATURE\u DD\u THIRD\u STATUS\u行
#如果启用\u功能\u DD\u状态
如果(G.flags&FLAG\u STATUS\u NOXFER)/*STATUS=NOXFER active*/
返回;
//TODO:status=none是否应使dd完全停止对USR1的反应?
//到目前为止,我们对此做出反应(我们打印统计数据),
//status=none仅抑制非USR1生成的最终状态消息。
#恩迪夫
fprintf(stderr,“%llu字节(%sB)已复制,”,
G.总字节数,
/*显示小数位数,使用后缀*/
使人可读(G.总字节数,1,0)
);
/*角落案例:
*/busybox-dd/dev/null
*/总线盒dd bs=1M计数=2000/dev/null
*(回显完成)|/busybox dd>/dev/null
*(睡眠1;回显完成)|/busybox dd>/dev/null
*/
秒=(现在-开始时间)/1000000.0;
字节/秒=总字节/秒;
fprintf(标准,“%f秒,%sB/s\n”,
秒,
/*显示小数位数,使用后缀*/
使人可读(字节秒,1,0)
);
#恩迪夫
}
>()
称为进程替换,不受sh
的支持,因此,/bin/sh:syntax error:unexpected redirection
error message.dd if=/dev/zero of=/tmp/test2.img bs=512 count=1000 2>&1 | grep copied不是标准的不幸的是,主机上的dd版本与容器内的版本不同,是的,最简单的解决方法是使用其他dd二进制文件,对于alpine,即从coreutils软件包(该软件包专门为我的容器提供所述输出),它需要从alpine:latest运行apk--no cache add coreutils
#if ENABLE_FEATURE_DD_THIRD_STATUS_LINE
# if ENABLE_FEATURE_DD_STATUS
if (G.flags & FLAG_STATUS_NOXFER) /* status=noxfer active? */
return;
//TODO: should status=none make dd stop reacting to USR1 entirely?
//So far we react to it (we print the stats),
//status=none only suppresses final, non-USR1 generated status message.
# endif
fprintf(stderr, "%llu bytes (%sB) copied, ",
G.total_bytes,
/* show fractional digit, use suffixes */
make_human_readable_str(G.total_bytes, 1, 0)
);
/* Corner cases:
* ./busybox dd </dev/null >/dev/null
* ./busybox dd bs=1M count=2000 </dev/zero >/dev/null
* (echo DONE) | ./busybox dd >/dev/null
* (sleep 1; echo DONE) | ./busybox dd >/dev/null
*/
seconds = (now_us - G.begin_time_us) / 1000000.0;
bytes_sec = G.total_bytes / seconds;
fprintf(stderr, "%f seconds, %sB/s\n",
seconds,
/* show fractional digit, use suffixes */
make_human_readable_str(bytes_sec, 1, 0)
);
#endif
}