如何用 dd 检测文件结尾?

如何用 dd 检测文件结尾?

我创建了一个 10MB 的测试文件:

dd if=/dev/zero of=file.txt count=1024 bs=10240

然后,我编写了下面的脚本来分块复制此文件。但看起来 dd 没有检测到 EOF,并且它总是返回 0,所以 while 循环会永远持续下去。

#!/bin/sh

block_size=1048576
count=0
retval=0
while true
do
        dd if=./file.txt of=other.txt bs=${block_size} seek=${count} skip=${count} status=none
        retval=$?
        if [[ $retval -ne 0 ]]; then
                break
        fi
        count=$((count + 1))
done

那么,当 dd 超过 EOF 时,如何让它返回差异代码?

答案1

我不知道你为什么需要这个装置;也许是为了学习目的。好的,下面是更复杂的装置:

#!/bin/bash

block_size=1048576   # must be a plain number, without any suffix
count=0
while true
do
   retbytes=`dd if=./file.txt bs=$block_size skip=$count count=1 status=none |
             tee >(dd of=other.txt bs=$block_size seek=$count status=none) |
             wc -c`
   [ "$retbytes" -eq "$block_size" ] || break
   count=$((count + 1))
done

您的原始脚本使用了sh[[。这不起作用。在我的版本中,[在需要它的地方就足够了(sh可以理解),但bash由于>(…)其他地方的语法,我无论如何都需要它。

file.txt您可能没有注意到,但您的脚本在第一遍就处理了整个过程,因为您没有告诉dd它在第一块之后停止。(注意dd 分块进行,即,您运行的唯一第一个命令dd会执行您希望整个脚本执行的操作)。稍后,在循环中连续的dd-s 再次覆盖的次数越来越少(因为它们跳过的次数越来越多);每次都持续到结束file.txt。它们的工作完全没用(除非在此期间输入文件发生变化)。我认为您的意图是什么count=1

我的脚本的工作原理如下:

  1. 它使用单独的dd-s 来表示阅读和写作。
  2. tee分叉读取的输出dd。一份副本发送给写入dd
  3. 相同的数据到达wc -c,此工具会告知其获得的字节数。
  4. 如果该数字与我们的块大小不匹配,则循环终止。

注意$block_size必须采用能够与 的输出进行比较的格式。因此,尽管能够理解选项中的一些wc后缀,但它必须是没有任何后缀的纯数字。ddbs=

相关内容