将输出从 'dd' 发送到 awk/sed/grep

将输出从 'dd' 发送到 awk/sed/grep

我正在尝试使用 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,您可以使用它|&来代替|它,这也将重定向STDERRSTDIN第二个命令,例如:

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."

相关内容