我正在尝试使用 dd 来估算计算机的写入速度:
dd if=/dev/urandom of=/dev/null bs=1K count=10000
给出以下输出
10000+0 records in
10000+0 records out
10240000 bytes (10 MB) copied, 0.746313 s, 13.7 MB/s
如何将“13.7 MB/s”放入 bash 变量中?我尝试将 dd 的输出通过管道传输到 awk、sed 和 grep 等程序,但无济于事。
os.system(...)
最终,我通过 python 脚本调用它。如果有人知道在 python 中获得类似结果的更直接方法,我也会对此感兴趣。我试图根据文件大小预测文件复制将花费多长时间。
任何帮助将不胜感激。
答案1
问题是您从 dd 指定的输出转到STDERR
而不是STDOUT
因此您还必须重定向STDERR
而不仅仅是STDOUT
。
对于 bash 和 zsh,您可以使用它|&
来代替|
它,这也将重定向STDERR
到STDIN
第二个命令,例如:
dd if=/dev/urandom of=/dev/null bs=1K count=10000 |& awk '/copied/ {print $8 " " $9}'
更通用的方法是使用 显式重定向 STDERR 2>&1
,例如:
dd if=/dev/urandom of=/dev/null bs=1K count=10000 2>&1 | awk '/copied/ {print $8 " " $9}'
对于 python 部分,请查看 subprocess 模块并Popen
尤其。
答案2
var=$(dd if=/dev/urandom of=/dev/null bs=1K count=10000 2>&1)
var=$(echo ${var##*,})
答案3
自从重击以来参数扩展避免使用外部命令,这是1_CR提出的一个很好且优雅的解决方案。
然而他的命题返回了错误的值(即只有逗号后面的值):
$ var=$(dd if=/dev/urandom of=/dev/null bs=1K count=10000 2>&1)
$ var=$(echo ${var##*,})
$ echo $var
8 MB/s # the wrong value
虽然以下正确答案会给出:
$ var=$(dd if=/dev/urandom of=/dev/null bs=1K count=10000 2>&1)
$ var=$(echo ${var##*s,})
$ echo $var
11,8 MB/s # the right value
答案4
主题的另一个变体,获取所有相关字段,避免对 awk 或 sed 的外部调用(使用 read,在 bash 中是内置的)
IFS=' +' read in_full in_part _x _x \
out_full out_part _x _x \
bytes _x _x _x _x seconds _x speed speed_units < <(
echo $(dd if=/dev/zero of=/dev/null bs=1024 count=7 2>&1)
)
echo -e "$bytes bytes were read in $seconds seconds, speed was $speed $speed_units.\n$in_full full blocks, and $in_part partial blocks were read in.\n$out_full full blocks, and $out_part partial blocks were written out."
一行中相同的内容(没有 \ 换行符)
IFS=' +' read in_full in_part _x _x out_full out_part _x _x bytes _x _x _x _x seconds _x speed speed_units < <( echo $(dd if=/dev/zero of=/dev/null bs=1024 count=7 2>&1) )
echo -e "$bytes bytes were read in $seconds seconds, speed was $speed $speed_units.\n$in_full full blocks, and $in_part partial blocks were read in.\n$out_full full blocks, and $out_part partial blocks were written out."