dd skip | seekオフセットを16進数として渡す


11
# dd if=2013-Aug-uptime.csv bs=1 count=1 skip=3 2> /dev/null
d
# dd if=2013-Aug-uptime.csv bs=1 count=1 skip=0x3 2> /dev/null
f

2番目のコマンドが異なる値を出力するのはなぜですか?

skip | seekオフセットをdd16進数値として渡すことは可能ですか?

回答:


18

2番目のコマンドが異なる値を出力するのはなぜですか?

歴史的な理由により、は乗算演算子ddと見なさxれます。したがって0x3、0と評価されます。

skip | seekオフセットを16進値としてddに渡すことは可能ですか?

私の知る限り、直接ではありません。演算子を使用した乗算と同様に、「512で乗算する」(0x200)と「1024で乗算する」(0x400)を意味するx任意の数の接尾辞を付けることができます。GNUはあなたにもサフィックスを使用することができDDが、、、、、およびそれぞれ、20、30、40、50、60、70、80又は90のパワーを2によって乗算を意味するように、あなたは除いて大文字または小文字を使用することができ以下のための接尾辞。(他の多くの可能な接尾辞があります。例えば、「10による乗算手段18」と手段「乗算2により50」。を参照してください。あなたはGNUのインストールを持っている場合は、より多くの情報のため。)bKMGTPEZYbEBPiBinfo coreutils "block size"

上記の難解で時代錯誤的で、マニアックで不条理なところまで出てくるかもしれません。心配しないでください。あなたは一人ではありません。幸い、すべてを無視して、代わりにシェルの算術置換を使用できます(Bashや他のPosix準拠のシェル、一部の非Posixシェルは機能します)。シェルは16進数を理解し、通常の方法で記述されたあらゆる範囲の算術演算子を許可します。式を$((...))次で囲む必要があります。

# dd if=2013-Aug-uptime.csv bs=1 count=$((0x2B * 1024)) skip=$((0x37))

$((...))POSIX算術展開であることに注意してください。これはbash固有ではありません。これを使用bashするために使用する必要はありません。どのPOSIXシェルでも実行できます。ただしbash、を含む多くのシェルでは単語分割されるため、引用する必要があります。
ステファンChazelas

@StephaneChazelas:それは本当です、それはbash固有ではありません。ただし、引用符は必要ありません。(Posix:「式は、二重引用符内にあるかのように扱われます。ただし、式内の二重引用符は特別に扱われません。」)式に変数があり、その値にセパレータが含まれている場合、その場合、それは有効な数ではありません。の周りに引用符を付けて$((...))も何も変わりません。私が引用がどこで何をするかを考えることができる唯一のケースは、あなたIFS=4がそのようなものを持っていたが、それが他のあらゆる種類の混乱を引き起こすであろう場合です。
rici 2013

あなたが引用するセクションは、中身について$((...))です。POSIXは、の展開が$((...))単語分割の対象であることを明確にしています。コマンド/算術/変数の展開を引用符で囲まずにリストコンテキストに残すのは、split + glob演算子です。IFS = 4を設定しても、split + glob演算子を必要としない場所で使用しない場合は、あらゆる種類の問題が発生するわけではなく、そのsplit + glob演算子が必要になるたびにIFSを設定します。
ステファンChazelas

@StephaneChazelas:はい、数値の結果は単語分割の影響を受けます。しかし、それは整数です。IFS数字を含む何かに設定した場合、私がこれまでに行ったことがないと思うものは、引用する必要があります。たぶんそれをしていれば、何気なくしそうなことはほとんどないので、その必要性に気づくでしょう。または、少なくとも、それは私がする可能性が高いものではありません。私はあなたのために話すつもりはありません。
rici 2013

1
@ogurets:どのシェルを使用していますか?(バージョンを含めてください)。
rici

0

私はこれが古いスレッドであることを知っていますが、特に私のような馬鹿が行き、誤ってfileBがまだチェックインされていないgitにバックアップされていないbash履歴から 'cp fileA fileB'を呼び出して実行する場合、問題はこれまでと同様に重要ですアップ、そして徹夜後に数時間のコーディングを含む:-/

このスレッドの概念のおかげで、失われたファイルを完全に回復することができましたが、32Gbのディスクと非常に少ないRAM(Ubuntu 18.04を実行)を備えたリモートの仮想プライベートサーバーで私のものを失いました。上記はすぐに「メモリ不足」で死ぬ

私の場合、それがhexdump -C /dev/sdX1 | grep 'shortString'私の助けになりました。grepとは異なり、それは16進数の非常に狭いASCII表現のみを表示するため、短い一意の文字列のみを探すことが重要であり、それでもラップできることに注意してください。一致した場所で16進数のアドレスが出力されたら、上記と同じ方法で 'dd'を使用できましたが、デフォルトのブロックサイズは4096であることがわかりました。 16進バイトのアドレスを10進数に変換しますが、4096で割ってddのskipパラメータの4kブロックにスケーリングします-この数値がddに対して大きすぎる場合、エラーメッセージはskip=渡された数値ではなく無効であることを訴えているようです。

$((0xabcd))簡単にhex-> dec変換するためにbashを使用することについてのヒントを追加した人々への称賛:-)

ただ私の最後の言葉-私の場合、同じファイルのいくつかのコピーがあり、それらはすべて近接していた。しかし、hexdumpによって報告された最高のアドレスから最低のアドレスを差し引くと、すべての可能なコピーを含む最大5MBの領域を特定できました。つまり、最低のアドレスでddをターゲットにして、その領域全体を一時ファイルに抽出できました。Vimエディターはバイナリコンテンツをかなり適切に処理するようになったので、一時ファイルを調べて必要に応じて再構成できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.