可以使用dd命令覆盖相邻的分区吗?

dd if=/dev/zero of=somepartition bs=512

也可以在somepartition之后擦除分区,或者停在somepartition的末尾吗?

5内核创建表示分区的块设备,例如/dev/sda1,以一种无法通过它们访问相邻存储的方式(假设在内核上次读取分区表后未对其进行修改)。如果可以通过这种方式访问相邻存储,那将被视为一个巨大的错误。 - David Foerster
5个回答

使用dd覆盖分区

dd是一个非常强大但也很危险的工具。它会按照你的指令执行而不会询问。所以如果你让它擦除了家庭照片,...只需要一个小的打字错误。

但是如果你仔细检查和反复核对,你可以使用它。

dd if=/dev/zero of=somepartition bs=512

或者我建议
dd if=/dev/zero of=/dev/sdxn bs=4096

在这种情况下,x是驱动器的盘符,n是分区号,块大小为4096字节可以加快写入过程。

重要的是您要写入一个分区。如果您写入整个驱动器(驱动器头部末尾)/dev/sdx,整个驱动器将被覆盖。但是写入分区时,会在分区末尾中断,并保留其后面的分区。(我在Lubuntu 16.04 LTS上现在进行了测试,所以我知道它是这样工作的。)

对于扩展分区的例外情况

对于扩展分区(用于在MSDOS分区表中拥有多于四个分区的容器),有一个例外情况。请参考以下链接进行了解:

我能使用dd制作“扩展”分区的镜像吗?

但是还有另一个问题。我在测试环境中测试了您的命令,当我想要制作扩展分区的镜像时,dd只读取了1 kibibyte(1024字节)。 我现在在Lubuntu 16.04 LTS上对USB闪盘进行了测试,这也适用于写入(以及读取)。只有第一个kibibyte被覆盖。 因此,总结一下,覆盖主分区和逻辑分区的工作原理与此答案的主要描述相符。但是不要使用此方法覆盖扩展分区,因为只会覆盖第一个kibibyte。扩展分区的逻辑分区将无法通过分区表找到,但其中存储的数据仍然存在。

我已经接受了,但如果是这样的话,这应该是正确的答案。 - LogicBreaker
4@LogicBreaker,也许你可以推迟接受。但这并不重要。更重要的是你要明白如何使用dd以及它的风险性,所以在使用时要非常小心。祝你好运 :-) 总的来说,你应该始终备份所有文件,那些你不能承受丢失的文件。 - sudodus
1当写入裸分区时,您没有太多选择。我已经移动了,否则会对其他人产生误导。 - LogicBreaker
没错,@LogicBreaker。 - sudodus
1这就是为什么用户通常无法访问/dev/* "文件"的原因。 - Thorbjørn Ravn Andersen
1如果这是你家庭照片的唯一副本,没有备份的话,那么你随时都有可能因为偷窃、火灾、意外或者简单的硬件故障而失去它们 :-) - user334639

我认为你的问题基于对dd(实际上是Unix类操作系统)工作原理的根本误解: dd无法覆盖相邻分区,因为dd根本无法覆盖分区,就是这样。 dd只是简单地写入文件。仅此而已。
现在,如果你传递给dd一个代表多个分区的文件,那么dd将会覆盖该文件。但在这种情况下,并不是dd超出分区末尾进行写入。dd仍然会写入直到文件末尾,仅限于文件末尾。
但是,如果你给dd传递一个只表示一个分区的文件,那么dd不会写入超过这个分区末尾的内容。再次强调,这与dd无关。dd只会写入你指定的文件。这个文件代表一个单独的分区,在这种情况下,是由内核中的块设备驱动程序确保的。dd与此无关。
简而言之:dd写入文件。这些文件代表什么,与dd无关。dd对分区一无所知。

嗯...只有写入文件的dd命令,无法用于写入原始分区。 - LogicBreaker
1正确。您不能使用dd命令直接写入原始分区。您只能写入文件。当然,您可以将数据写入代表分区的块设备文件(例如/dev/sda1),但是您无法直接写入原始分区。由于您只能写入代表分区的文件,因此无法超出分区的末尾进行写入,因为该文件仅代表分区本身,而不包括分区末尾之后的部分。 - Jörg W Mittag
3Jorg是Unix哲学的主要思想之一 - “万物皆文件”,因此内核将分区、设备、端口等表示为文件。因此,可以使用每个可以写入文件的程序来写入分区或设备。内核的工作是强制执行分区边界。您可以在文本编辑器中打开/dev/sda并更改数据,dd与其他任何程序一样能够访问分区。非常好的答案! - Sergey

写入分区设备不会超出该分区的范围,无论是使用dd还是其他任何工具。您需要使用整个磁盘设备才能在单个分区之外产生任何影响。
(注意:除非您的磁盘有重叠分区的分区表,这种情况应该永远不会发生。)

3另一个注意事项:如果你正在使用类似 LVM 的东西,向物理卷写入数据当然会影响到许多逻辑卷。 - Maxpm

有一种危险但罕见的特殊情况,即使没有错误的块设备驱动程序,也可能发生以下情况:

  • 磁盘上的分区表以某种方式更改,使得分区x的大小调整到比之前的边界更低。要么在其后面调整分区y的起始边界,要么在该空间中添加一个新的分区y。
  • 通过与分区表无关的手段(例如使用带有跳过/计数选项的dd命令)将相关数据填充到分区y中,这些手段可以作用于整个磁盘块设备(例如/dev/sda)。
  • 未发出或由于设备繁忙而失败的ioctl命令告诉内核重新读取分区表。
  • 任何尝试向分区x写入数据的进程都会一直写入,直到遇到错误条件为止。

你在使用dd命令时必须小心,因为如果出错的话可能会覆盖你预期之外的内容,这取决于你使用dd命令的目的(原帖中对dd的使用方式和具体语法并不明确)。
如果你指定了一个分区,它将会一直写入该分区直到分区满为止。
如果你犯了一个错误,比如将整个驱动器作为输入文件(例如of=/dev/sda),dd将会从头到尾地写入整个驱动器,忽略并覆盖你的分区表。
你也可以使用dd命令来覆盖已删除的文件(已删除的文件可能仍然存在于分区中,并且可以通过各种恢复工具以不同程度的成功进行发现,直到被覆盖)。在这种情况下,你可以使用dd命令向一个文件中写入数据来填充空闲空间。
dd if=/dev/zero of=/path/to/mount_point/zero_file bs=4096
rm -f /path/to/mount_point/zero_file

根据你所做的事情,你可能希望使用其他工具来安全删除文件。请参考如何以安全方式删除文件?以获取选择。

所以,在示例1中指定文件而不是分区并运行dd,没有任何区别吗? - LogicBreaker
你可以指定一个分区,但是在我看来,只要为了保险起见,指定一个文件也同样简单。 - Panther
我的意思是,当给定一个文件作为输入时,dd命令会不会在文件结束处停止。 - LogicBreaker
在写入文件时,一旦分区已满,dd 将停止并报错。然后您需要删除该文件。 - Panther
6如果你能够写入/dev/sdcX并成功跨越分区边界进行写入,那不是dd忽略了分区表,而是内核中的块设备驱动程序存在错误并忽略了分区表。 - rackandboneman
1@sudodus dd并不是那么底层。实际上,大多数人使用dd做的事情都可以用cat来完成。事实上,cat稍微快一些,因为它使用的默认块比dd大。所有的底层代码都在内核中。驱动程序并不真正关心你是使用dd还是cat - kasperd
1@sudodus - 对于造成困惑,我很抱歉,我的表达不够清晰。dd确实可以持续写入,这取决于你告诉它要做什么。dd if=/dev/zero of=/dev/sda bs=512 count=1 或者 dd if=/dev/zero of=/dev/sda bs=512 是一些例子。使用第二个命令,它将持续写入并填满整个磁盘,"忽略"分区表。如果你指定一个分区 dd if=/dev/zero of=/dev/sda1,它将不会超出该分区。这有点取决于你想用dd做什么。 - Panther
文件上的写入取决于文件系统,并不能保证在分区上不会留下敏感信息。我建议删除这个回答。 - user334639
那不是问题。问题是dd能否在分区之外写入,而不是如何安全删除文件。答案是取决于你如何运行dd,我已经解释过了。将所有零写入一个文件并删除该文件将通过覆盖硬盘来安全删除已删除的文件,但正如我在回答中指出的那样,有更好的方法来删除文件。我建议你阅读问题并向提问者要求澄清,而不是基于这些假设来建议删除我的答案。 - Panther
1@Panther 这个问题明确指出了 of=somepartition,所以不适用于你写入整个磁盘设备的情况。dd 无法绕过设备驱动程序的限制。 - Barmar
1@Bamar 看看我已经评论过了。我见过很多用户把 $somepartition 误认为 /dev/sda。 - Panther