web-dev-qa-db-ja.com

'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 /秒」をbash変数に入れるにはどうすればよいですか?出力をddからawk、sed、grepなどのprogsにパイプして、役に立たないようにしてみました。

最終的には、pythonスクリプト内からos.system(...)を介してこれを呼び出しています。もし誰かがより直接的な方法を知っていれば、python私もそれに興味があります。ファイルサイズに基づいて、ファイルのコピーにかかる時間を予測しようとしています。

どんな助けでも大歓迎です。

7
user19082

問題は、ddからの指定された出力がSTDERRではなくSTDOUTに送られるため、STDERRだけでなくSTDOUTもリダイレクトする必要があることです。

Bashとzshの場合、|&の代わりに|を使用できます。これにより、2番目のコマンドの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の部分については、サブプロセスモジュール、特に Popen を見てください。

9
Ulrich Dangel
var=$(dd if=/dev/urandom of=/dev/null bs=1K count=10000 2>&1)
var=$(echo ${var##*,})
2
iruvar

Bash パラメータ拡張 は外部コマンドの使用を回避するため、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
1
denaitre

テーマの別のバリエーションで、関連するすべてのフィールドを取得し、awkまたはsedへの外部呼び出しを回避します(bashに組み込まれているreadを使用します)

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

1行で同じこと(\改行なし)

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