如何确定eod

时间:2014-07-29 08:02:44

标签: bash shell dd mt

我想使用脚本来读取DDS磁带的各种分区 目前我正在使用以下脚本

TAPE=/dev/nst0         
BLOCK_SIZE=32768        
COUNTER=1
END_OF_DATA=120

while [  $COUNTER -lt $END_OF_DATA ] 
do      
       dd if=$TAPE bs=$BLOCK_SIZE of=file_$COUNTER  
       let COUNTER+=1 
done

但是,正如您所看到的,我的脚本最多可以读取120个分区。

如何修改此代码以使脚本能够自动识别磁带数据的结尾

由于

2 个答案:

答案 0 :(得分:2)

您可以继续将报告与块大小进行比较。是的,你必须只打开一次设备并继续阅读它。

TAPE=/dev/nst0 
BLOCK_SIZE=32768
COUNTER=1

while [ "$(dd bs="$BLOCK_SIZE" of="file_$COUNTER" 2>&1 count=1 | awk '/bytes/ { print $1 }')" -eq "$BLOCK_SIZE" ]; do
    let ++COUNTER
done < "$TAPE"

使用文件测试脚本。

如果读取的最后一个字节数仅为0,您也可以删除最后一个文件:

while
    BYTES_READ=$(dd bs="$BLOCK_SIZE" of="file_$COUNTER" 2>&1 count=1 | awk '/bytes/ { print $1 }')
    [ "$BYTES_READ" -eq "$BLOCK_SIZE" ]
do
    let ++COUNTER
done < "$TAPE"

[ "$BYTES_READ" -eq 0 ] && rm -f "file_$COUNTER"

如果要在处理磁带时发送消息,可以使用重定向并使用其他文件描述符:

TAPE=temp
BLOCK_SIZE=32768
COUNTER=1

while
    FILE="file_$COUNTER"
    echo "Reading $BLOCK_SIZE from $TAPE and writing it to file $FILE."
    BYTES_READ=$(dd bs="$BLOCK_SIZE" of="$FILE" count=1 2>&1 <&4 | awk '/bytes/ { print $1 }')
    echo "$BYTES_READ bytes read."
    [ "$BYTES_READ" -eq "$BLOCK_SIZE" ]
do
    let ++COUNTER
done 4< "$TAPE"

[ "$BYTES_READ" -eq 0 ] && rm -f "$FILE"

示例输出:

Reading 32768 from temp and writing it to file file_1.
32768 bytes read.
Reading 32768 from temp and writing it to file file_2.
32768 bytes read.
Reading 32768 from temp and writing it to file file_3.
32768 bytes read.
Reading 32768 from temp and writing it to file file_4.
32768 bytes read.
Reading 32768 from temp and writing it to file file_5.
32268 bytes read.

另一个选择是将echo发送到/dev/stderr

echo "Reading $BLOCK_SIZE from $TAPE and writing it to file $FILE." >&2

为了使它快一点,在子shell中使用exec来防止额外的fork:

BYTES_READ=$(exec dd ...)

答案 1 :(得分:1)

正如我在评论中所说,我对此问题并不十分熟悉,但由于dd在每个分区的末尾停止”,为什么不简单阅读,直到没有其他内容可阅读?

TAPE=/dev/nst0         
BLOCK_SIZE=32768        
COUNTER=1

while true 
do      
       dd if=$TAPE bs=$BLOCK_SIZE of=file_$COUNTER

       if [ \! -s file_$COUNTER ]
       then
               # clean-up empty file and exit the loop
               rm file_$COUNTER
               break
       fi
       let COUNTER+=1 
done

(未测试的)