私は最近、私たちが使用することができます実現cat
限りdd
、それはだ、実際よりも速くdd
これは、dd
パフォーマンスだけでなく、ブロックサイズが正確に重要であるテープを扱うのに役立つことを知っています。しかし、最近では、dd
できないことcat
ができる状況はありますか?(ここでは、パフォーマンスの差は20%未満であると見なします。)
具体的な例がいいでしょう!
私は最近、私たちが使用することができます実現cat
限りdd
、それはだ、実際よりも速くdd
これは、dd
パフォーマンスだけでなく、ブロックサイズが正確に重要であるテープを扱うのに役立つことを知っています。しかし、最近では、dd
できないことcat
ができる状況はありますか?(ここでは、パフォーマンスの差は20%未満であると見なします。)
具体的な例がいいでしょう!
回答:
外観dd
は、外部の外観(パラメーターの受け渡し)を保持するIBMオペレーティングシステムのツールであり、非常にまれにしか使用されない機能(EBCDICからASCIIへの変換やエンディアンの反転など、今日では一般的な必要性はありません)を実行します。
私が考えるために使用されることがdd
速く(起因するバッファリングをより効率的に使用する)同じディスク上のデータの大きなブロックをコピーするためだったが、これは真実ではない、少なくとも今日のLinuxシステムでは、。
いくつかdd
のオプションは、読み取りが実際にブロックで実行されるテープを扱うときに便利だと思います(テープドライバーは、ディスクドライバーのようにストレージメディア上のブロックを隠しません)。しかし、私はその詳細を知りません。
dd
他のPOSIXツールでは(簡単に)できないことの1つは、ストリームの最初のNバイトを取得することです。多くのシステムでを使用できますhead -c 42
がhead -c
、は一般的ですが、POSIXには含まれていません(OpenBSDなどでは今日利用できません)。(tail -c
POSIXです。)また、head -c
存在する場合でも、ソースから多くのバイトを読み取る可能性があります(内部でstdioバッファリングを使用するため)。これは、読み取りだけが有効な特殊ファイルから読み取る場合に問題になります。(現在のGNU coreutilsはで正確なカウントを読み取りhead -c
ますが、FreeBSDとNetBSDはstdioを使用します。)
より一般的には、dd
Unixツールの中で一意である基本的なファイルAPIへのインターフェイスを提供します:のみdd
可能上書きまたは切り捨てファイルを任意の時点で、または求めてファイルに。(これはdd
のユニークな能力であり、大きな能力です。奇妙なdd
ことに、他のツールでできることで十分に知られています。)
>
、シェルでリダイレクトを使用する場合にも発生します。>>
シェルでリダイレクトするか、でファイルのコンテンツに追加できますtee -a
。特定のポイントの後にすべてのデータを削除してファイルを短くしたい場合、これはtruncate
関数を介して基礎となるカーネルとC APIでサポートされますが、以下を除くdd
コマンドラインツールでは公開されません:
dd if=/dev/null of=/file/to/truncate seek=1 bs=123456 # truncate file to 123456 bytes
あなたはファイルの途中でデータを上書きする場合は、再び、これはでunderyling APIで可能です開い切り捨て(と呼ばずに書き込み用のファイルをlseek
必要に応じて任意の位置に移動する)が、唯一dd
せずにファイルを開くことができます切り捨てまたは追加、またはシェルからのシーク(より複雑な例)。
# zero out the second kB block in the file (i.e. bytes 1024 to 2047)
dd if=/dev/zero of=/path/to/file bs=1024 seek=1 count=1 conv=notrunc
だから…システムツールとしては、dd
ほとんど役に立たない。テキスト(またはバイナリファイル)処理ツールとして、非常に価値があります!
trunc
そしてseek
から使用可能ですdd
)。
dd
stdioバッファリングにより未読データを破壊する可能性なしに、シークできないファイル記述子からバイナリデータを読み取ることができます。例えばここを参照してください:etalabs.net/sh_tricks.html
head -c N
呼び出すread
ことはありません。NetBSD5.1では、をhead -c
呼び出しますgetc
。FreeBSD 7.4では、をhead -c
呼び出しますfread
。
dd
はO_DIRECT(など)をシェルスクリプトに公開しますが、これもユニークだと思います。
このdd
コマンドには、catが対応できない多くのオプションが含まれています。おそらくあなたの使用例では、猫は実行可能な代替品ですが、ddの代替品ではありません。
1つの例はdd
、全体ではなく何かの一部をコピーするために使用します。おそらく、デバイス上の既知の場所に基づいて、isoイメージの中央から一部のビットをリッピングしたり、ハードドライブからパーティションテーブルをリッピングしたい場合があります。ではdd
、あなたが開始を指定することができ、停止してこれらのアクションを許可数量オプション。
これらのオプションはdd
、粒度の細かいデータ操作に不可欠です。一方、cat
*はファイルオブジェクト、デバイス、またはストリーム全体に対してのみ操作できます。
*コメントでGillesが指摘したように、cat
他のツールと組み合わせて何かの部分を分離することは可能ですが、cat
それでもオブジェクト全体で動作します。
dd
実際には低レベルのデバイスとは何の関係もありません/dev
。他のデバイスと同様にエントリが必要です。を使用してパーティション全体をコピーしcat
たり、の一部をコピーできますtail +c $(($start+1)) | head -c $count
。
cat | head | tail
、最後の数MBを取得するために1.6 TBのディスクイメージをフィードすると、ディスクスピンアップは月を地球に近づけます。
誰もまだ作成するDDを使用することができることを言及していないスパースファイルをしかし、truncate
同じ目的のために使用することができます。
dd if=/dev/zero of=sparse-file bs=1 count=1 seek=10GB
これはほとんど瞬時であり、たとえばループバックファイルとして使用できる任意の大きなファイルを作成します。
loop=`losetup --show -f sparse-file`
mkfs.ext4 $loop
mkdir myloop
mount $loop myloop
良い点は、最初は単一のディスクスペースブロックのみを使用し、その後は必要に応じてのみ増加することです(10 GBファイルのext4フォーマットはシステムで291 MBを消費します)。使用du
-どのくらいのディスク容量が実際に使用されて見にls
ファイルがに成長する可能性の報告のみ最大サイズ。
ls -ls
スパースサイズを表示します。
dd of=sparse-file bs=1 count=0 seek=10G
はと同等truncate -s 10GB sparse-file
です。紛らわしいことに十分な、truncate
とdd
は正反対の解釈持ってGB
対をG
...
man dd
言う:MB =1000*1000, M =1024*1024
など。そしてman truncate
言う:MB 1000*1000, M 1024*1024
、違いはありません。私は両方を使用dd
してtruncate
のGNU coreutilsのから。あなたもそうするべきです!:-)
ここに私が長年にわたって思いついたいくつかのDDのトリックがあります。
EOF / ^ D / ^ Fが検出されない場合は、ddを使用してテキストファイルをホストに転送できます。指定されたバイト数の後に自動的に読み込みを停止するため。
昨年と同じように、リモートホストで非ttyシェルを取得でき、ファイルを転送する必要があるセキュリティ演習中にこれを使用しました。
実際、base64でエンコードし、低速で信頼性の高い純粋なbash base64デコードスクリプトを使用して、いくつかのバイナリファイルを作成しました。
dd of=textfile.txt bs=1 count=<size_of_data_in_paste_buffer>
非常にクールなトリックは、ddの実行中にUSR1シグナルを送信すると、現在のステータス(読み取りバイト、1秒あたりのバイト数)を送信することです。
これは、stdoutを介してデータを出力するプログラムの純粋なbash進行フィルターとして機能するように作成しました。(注:ほとんど何でもstdoutを介してデータを出力します-そうしないプログラムでは、/ dev / stdoutをファイル名として使用して、あなたに邪魔をしない場合はごまかすことができます。しかし、基本的には、Xを取得するたびにバイト数、ハッシュマークの印刷(ハッシュモードをオンにしたときの古い学校のFTPなど)
(注)プログレスファイルは不完全であり、これはほとんど概念実証でした。やり直した場合は、変数を使用するだけです。
dd bs=$BLKSZ of=${TMPFILE} 2>&1 \
| grep --line-buffered -E '[[:digit:]]* bytes' \
| awk '{ print $1 }' >> ${PROGRESS} &
while [[ $(pidof dd) -gt 1 ]]; do
# PROTIP: You can sleep partial seconds
sleep .5
# Force dd to update us on it's progress (which gets
# redirected to $PROGRESS file.
pkill -USR1 dd
local BYTES_THIS_CYCLE=$(tail -1 $PROGRESS)
local XFER_BLKS=$(((BYTES_THIS_CYCLE-BYTES_LAST_CYCLE)/BLKSZ))
if [ $XFER_BLKS -gt 0 ]; then
printf "#%0.s" $(seq 0 $XFER_BLKS)
BYTES_LAST_CYCLE=$BYTES_THIS_CYCLE
fi
done
匿名ファイルハンドルを介してtar入力を提供することにより、エラーなしで抽出できる署名済みtarファイルを、どのようにtmpファイルを使用して部分的なファイルデータを保存することなく取得できるかを示す非常に擬似的なコード例を次に示します。
generate_hash() {
echo "yay!"
}
# Create a tar file, generate a hash, append it to the end
tar -cf log.tar /var/log/* 2>/dev/null
TARFILE_SIZE=$(stat -f "%z" log.tar)
SIGNATURE=$(generate_hash log.tar)
echo $SIGNATURE >>log.tar
# Then, later, extract without getting an error..
tar xvf <(dd if=$OLDPWD/log.tar bs=1 count=${TARFILE_SIZE})
tl; drは次のとおりです。ddは非常に便利です。そして、これらは私の頭上から考えることができる3つの例にすぎません。
一部の出力コンテンツをリダイレクトできます。あなたが書く必要がある場合、それは特に便利ですsudo
:
echo some_content | sudo dd status=none of=output.txt
それに加えsudo
て:
echo some_content > output.txt
またはこれに:
echo some_content | sudo tee output.txt > /dev/null