有人可以向我解释以下答案吗: 如何将 Linux Mint 18 的 SSD 克隆到更大的 SSD
发生了什么事:
pv < /dev/sdX > /dev/sdY
PV => 用于定时其他命令的命令,但是“<源磁盘>”是什么?
我真的很想了解为什么这个答案有效。
答案1
Linux 中的许多命令都设计为以管道方式运行。这意味着您可以像这样链接它们:
command1 | command2 | … | commandN
在这种情况下,的标准输出 (stdout)command1
转到的标准输入 (stdin)command2
等等。命令可能会或可能不会使用其 stdin/stdout,具体取决于其设计和您提供的选项+操作数。您可以阅读手册以了解哪些命令可以这样工作。
管道符号 ( |
) 属于shell 语法. 正是 shell 安排了命令之间的连接(管道)。
在上面的例子中,管道中command1
没有前任也没有后继。在这种情况下,的 stdin和 stdout分别连接到 shell 认为是其 stdin 和 stdout 的东西。通常是终端。commandN
command1
commandN
您可以根据需要更改它。例如:
command1 <input | command2 | … | commandN >output
input
并且output
是文件(注意这是一个广义的术语)。现在,如果command1
从其 stdin 读取,则它会从 读取input
;如果commandN
写入其 stdout,则它会写入output
。(更多:如果command1
对其 stdin 执行任何操作,则它会对其执行任何操作input
等;例如,通常可以写入 stdin 或从 stdout 读取,因为这些只是文件描述符;这种情况相当罕见,不必担心)。
我更喜欢能够更清晰地显示数据流的语法(比较这个答案):
<input command1 | command2 | … | commandN >output
如果每个命令都设计为(并配置了适当的选项+操作数)从其标准输入读取并写入其标准输出,那么数据将从 流向input
。output
每个命令都会对数据流做一些事情(在这种情况下,“没有变化”也是“一些事情”)并将其进一步传递到管道中。这样,您就可以链接许多影响数据的“效果”。像这样工作的命令称为过滤器(尤其是当它们处理文本数据时)。
在 Unix 哲学中,工具应该只做一件事,并把它做好。这个想法是使用许多简单、定义良好的工具来实现你想要的。通常这意味着链接多个过滤器以获得一个复杂的过滤器。
另一方面,有一种情况是命令数量为 1。你可以只用一个命令从 读取input
、执行某项操作并向 写入output
:
<input command1 >output
# or equivalently
command1 <input >output
# or (extra spaces allowed)
command1 < input > output
再次强调,命令需要设计成这样工作。许多命令是这样的,有些则不是。如果您没有指定任何输入文件的路径(作为命令行操作数),或者指定的路径实际上是-
(一个公约)。请阅读相应的文档以了解特定命令的行为方式。
有问题的命令
pv < /dev/sdX > /dev/sdY
相当于
</dev/sdX pv >/dev/sdY
和pv
的设计工作方式如下。您可能认为是向 提供操作数< /dev/sdX >
的某种形式(语法)。但事实并非如此。和是两个单独的重定向,实际命令是没有参数的单独命令。/dev/sdX
pv
< /dev/sdX
> /dev/sdY
pv
由于pv
能够与其 stdin 和 stdout 一起工作,整行表示“从 读取/dev/sdX
,对数据流执行某些操作(无论pv
执行什么操作)并写入/dev/sdY
”。
pv
也会理解这一点:
pv /dev/sdX >/dev/sdY
在这种情况下,/dev/sdX
是 的命令行参数pv
。该工具将从指定的文件中读取并忽略其标准输入(仅因为它设计为以这种方式工作),因此效果基本相同。
您的目标是克隆,因此所需的“要做的事情”是“不改变”;您想要“从 读取/dev/sdX
,不改变任何内容并写入/dev/sdY
”。执行“不改变”的最基本程序(命令)是cat
。pv
那么为什么呢?
有许多可以执行“无变化”的命令。对于特定命令,执行“无变化”的能力可能是因为:
- “无变化”是命令设计用于执行的任务的一种特殊情况(“做一件事,并把它做好”,还记得吗?);如果有适当的选项(或没有适当的选项),任务就变成“无变化”;
- 该命令旨在传递未改变的数据,同时执行其他操作;这可能是:
- 分叉数据流,
- 提供缓冲区(在内存或磁盘上),
- 影响吞吐量,
- 显示吞吐量、进度或其他统计数据(通过单独的通道:标准错误,stderr,因此不会干扰 stdout),或记录到文件,
- 其他东西。
执行“无变化”的命令示例:
</dev/sdX cat >/dev/sdY
的主要目的cat
是连接多个文件(数据流)。当没有指定文件时(如本例),将使用 stdin。当只有一个输入流时,您将得到“无变化”。
</dev/sdX tee >/dev/sdY
主要目的tee
是分叉流。一份副本发送到 stdout,每个指定文件也获得一份副本。当没有指定文件时(如本例),您只会获得一份发送到 stdout 的副本,“无变化”。
</dev/sdX dd >/dev/sdY
dd
是克隆块设备的常用工具(比较这个答案), 但有怪癖。传统上,人们会使用if=/dev/sdX
和of=/dev/sdY
,没有它们,则分别使用 stdin 和 stdout。并且您希望使用bs=
以提高性能。某些选项或情况可能会使输出流与输入不同,但通常您仍会得到“无变化”(加上退出时向 stderr 提供一些统计信息dd
)。
</dev/sdX pv >/dev/sdY
这将向您显示进度和吞吐量。使用适当的选项,您可以限制吞吐量。数据流没有被破坏,因此您得到“无变化”。
</dev/sdX mbuffer >/dev/sdY
有点类似于pv
,此外,您还可以选择它使用的缓冲区的大小(在内存中或文件中)。数据流没有被破坏,因此您得到的是“无变化”。
请注意,还有另一个工具可以“读取input
、不更改任何内容并写入” output
。它是cp
。通常您可以像这样指定文件:
cp input output
这可能不明显但cp
可以克隆/dev/sdX
到/dev/sdY
:
cp /dev/sdX /dev/sdY
该工具并非设计为使用其 stdin 或 stdout,它需要路径。这将不起作用:
</dev/sdX cp >/dev/sdY
在现代 Linux 中,您可以cp
像这样使用它的 stdin 和 stdout:
<input cp /dev/stdin /dev/stdout >output
# or
<input cp /proc/self/fd/0 /proc/self/fd/1 >output
其中/dev/stdin
和分别/dev/stdout
链接到/proc/self/fd/0
和/proc/self/fd/1
。这些是内核提供的特殊文件。如果任何进程尝试打开/proc/self/fd/0
,它将获得自己的 stdin。和/proc/self/fd/1
stdout 也是如此。这样,您可以强制一些非管道友好进程使用重定向或在管道中工作。它几乎从来都没有什么用,而且可能会出现一些问题(通常命令出于某些原因不是管道友好的),我就不详述了。
答案2
答案3
<
重定向标准输入>
重定向标准输出
该命令将 /dev/sdX 作为输入(原始 USB 设备),并将新的更大 USB 笔写入 /dev/sdY。这甚至会重建分区表(通常位于第一个扇区)和原始笔的分区内容。