Bash
如何在塊設備上找到第一個非零字節,並帶有可選的偏移量?
我正在嘗試使用並列印其偏移量的塊設備上的第一個非零字節(從可選偏移量開始)
dd
,但我被卡住了。我沒有dd
在標題中提到,因為我認為可能有比dd
這樣做更合適的工具,但我認為dd
應該是一個好的開始。如果您知道更合適的工具和/或更有效的方法來實現我的目標,那也很好。同時,我將向您展示到目前為止我
dd
在 bash 中的進展情況。#!/bin/bash # infile is just a temporary test file for now, which will be replaced with /dev/sdb, for instance infile=test.txt offset=0 while true; do byte=`dd status='none' bs=1 count=1 if="$infile" skip=$offset` ret=$? # the following doesn't appear to work # ret is always 0, even when the end of file/device is reached # how do I correctly determine if dd has reached the end of file/device? if [ $ret -gt 0 ]; then echo 'error, or end of file reached' break fi # I don't know how to correctly determine if the byte is non-zero # how do I determine if the read byte is non-zero? if [ $byte ???? ]; then echo "non-zero byte found at $offset" break fi ((++offset)) done
如您所見,我遇到了兩個我不知道如何解決
的問題:到達文件/設備末尾時如何進行
while
循環?給出一個退出程式碼,而我期望一個非零退出程式碼。 灣。如何評估在標準輸出上讀取和返回的字節是否非零?我想我在某處讀到過,在 bash 中也應該特別注意字節,但我什至不確定這是否與這種情況有關。break``dd``dd``0
dd``\0
你能給我一些關於如何進行的提示,或者建議和替代方法來實現我的目標嗎?
您可以使用 來執行此操作
cmp
,與 相比/dev/zero
:cmp /path/to/block-device /dev/zero
cmp
會給你第一個非零字節的偏移量。如果您想跳過字節,您可以使用 GNU
cmp
的-i
選項,或者如果您不使用 GNUcmp
,請使用以下命令提供適當的數據dd
:cmp -i 100 /path/to/block-device /dev/zero dd if=/path/to/block-device bs=1 skip=100 | cmp - /dev/zero
這適用於任何文件,而不僅僅是塊設備。
斯蒂芬基特的回答使這有點毫無意義(它更簡潔,速度快一個數量級以上),但您可以選擇(十六進制)轉儲設備的內容,每行一個字節,並將其通過管道傳輸到列印第一個字節的地址的程序,它的表示不是
00
,並在找到它後立即退出:od -Ad -w1 -tx1 /dev/device | awk '$2 && $2 != "00" { print $1 + 1; exit }'
od
的-j
選項允許您有選擇地選擇要跳過的字節數(在輸入的開頭)。更快的變化(感謝Peter Cordes的評論)需要更多的輸入:
od -Ad -tx1 | awk ' { for (i=2; i<=NF; i++) if ($i != "00") { print ($1 + i -1) exit } }'
允許
od
以首選格式輸出數據需要計算第一個非零字節的偏移量,方法是將其在行中出現的位置添加到行地址。