什么是 pv 命令?
pv 是一个命令行工具,它的全称是 "Pipe Viewer"(管道查看器),它的主要作用是在数据流经管道时,提供一个可视化的进度指示器。

当你执行一个可能需要很长时间的命令,比如复制一个大文件、压缩一个目录或者通过网络传输数据时,你通常无法知道进度,只能干等着。pv 就解决了这个问题,它会显示:
- 已传输的数据量 ( 1.2G)
- 经过的时间 ( 00:01:15)
- 预计剩余时间 ( ETA 00:02:30)
- 当前传输速率 ( 24.3M)
pv 本身并不处理数据,它只是“监听”数据流,并显示进度信息,它就像一个透明的中间人,让数据从一端流入,再从另一端原封不动地流出,同时告诉你数据流得有多快。
安装 pv
pv 通常不是 Linux 系统的默认组件,你需要先安装它,在大多数发行版中,安装非常简单:
基于 Debian/Ubuntu 的系统:

sudo apt update sudo apt install pv
基于 RedHat/CentOS/Fedora 的系统:
sudo yum install pv # 或者对于较新的版本 sudo dnf install pv
基于 Arch Linux 的系统:
sudo pacman -S pv
pv 的基本用法和工作原理
pv 的核心思想是作为管道的一部分,它的基本语法是:
pv [选项] [文件名]
当你不指定文件名时,pv 会从标准输入读取数据,并将其输出到标准输出。

示例1:显示一个文件的传输进度
假设你有一个大文件 large_file.iso,你想用 pv 显示它的内容,然后通过管道传给另一个命令(gzip 进行压缩)。
pv large_file.iso | gzip > large_file.iso.gz
命令解释:
pv large_file.iso:pv开始读取large_file.iso,并立即在终端显示进度信息(如31G 0:00:15 [ 154MB/s] [=======> ] 1% ETA 0:25:30)。- 管道符,将
pv输出的数据(即large_file.iso的内容)传递给下一个命令。 gzip: 接收数据流并进行压缩。> large_file.iso.gz: 将gzip压缩后的结果保存到新文件中。
你会看到一个动态更新的进度条,让你对整个过程了如指掌。
示例2:显示输入数据的进度
如果你没有具体的文件,而是从其他命令获取数据流,同样可以使用 pv。
tar -czf - /var/log | pv > backup_logs.tar.gz
命令解释:
tar -czf - /var/log:tar命令创建/var/log目录的压缩包。-f -表示将压缩结果输出到标准输出(而不是文件)。- 将
tar的输出传递给pv。 pv: 显示从tar接收到的数据流的进度。> backup_logs.tar.gz: 将最终结果保存到文件。
常用选项
pv 提供了许多有用的选项来定制输出。
| 选项 | 说明 | 示例 |
|---|---|---|
-p, --progress |
显示进度条、百分比、已用时间和 ETA,这是默认行为。 | pv -p file.img |
-t, --timer |
显示已用时间。 | pv -t file.img |
-e, --eta |
显示预计剩余时间。 | pv -e file.img |
-r, --rate |
显示传输速率。 | pv -r file.img |
-b, --bytes |
以字节为单位显示所有计数,默认情况下,它会自动选择 KB、MB、GB 等单位。 | pv -b file.img |
-n, --numeric |
以百分比形式输出进度,而不是进度条,这对于在脚本中捕获进度非常有用。 | pv -n large_file.iso \| dialog --gauge "Progress" 10 70 |
-q, --quiet |
不输出任何信息,只将数据原封不动地传递下去,这在你只想使用 pv 的某些功能(如限制速率)而不想看到输出时很有用。 |
pv -q file.img \| other_command |
-L, --rate-limit RATE |
限制传输速率为指定的值,单位可以是 K, M, G 等。 |
pv -L 1M large_file.iso \| netcat ... (限制为 1MB/s) |
-W, --wait |
当输入数据流暂时没有数据时,pv 会等待,而不是立即退出。 |
|
-f, --force |
即使输出到一个终端,也强制非交互式输出。 | |
-c, --cursor |
在显示进度时,不换行,而是使用回车符覆盖上一行。 |
综合应用示例
示例1:限制网络传输速率
当你使用 netcat 或 ssh 传输大文件时,可能会占用大量带宽,影响其他网络活动,可以使用 pv 来限制速率。
# 将本地文件通过 nc 发送到远程服务器,限制速率为 2MB/s pv -L 2M large_file.iso | nc -l 12345
在远程服务器上,你用以下命令接收:
nc [本地IP] 12345 > received_file.iso
示例2:在脚本中获取进度百分比
如果你想在脚本中根据进度条更新一个图形界面或执行其他操作,-n 选项就派上用场了。
#!/bin/bash # 使用 dialog 创建一个进度条窗口 dialog --title "File Copy" --gauge "Please wait..." 10 70 0 # 执行复制操作,并通过 pv 获取百分比 pv -n /path/to/source | dd of=/path/to/dest 2>/dev/null | dialog --gauge "Copying..." 10 70 # 复制完成后,清除 dialog 窗口 clear echo "Copy complete!"
示例3:显示总数据量
pv 可以在开始处理前先扫描文件以确定总大小,这样 ETA 会更准确。
# 先用 pv 扫描文件大小,然后再实际传输 pv -p -b -r -e -s $(du -sb /path/to/directory | cut -f1) /path/to/directory | tar -czf - -C /path/to . | cat > backup.tar.gz
du -sb ...: 获取目录的总字节数。-s SIZE: 指定输入数据的总大小。tar -czf - -C /path/to .: 从/path/to目录打包, 表示打包当前目录下的所有内容。
pv vs dd
dd 是一个底层的、功能强大的数据复制工具,但它的输出非常简单,通常只显示最终统计信息,且无法实时显示进度,这就是 pv 成为 dd 最佳“伴侣”的原因。
传统 dd 命令:
dd if=source.img of=dest.img bs=4M # 输出: # 123456+0 records in # 123456+0 records out # 515396075520 bytes (515 GB, 480 GiB) copied, 325.456 s, 1.6 GB/s
结合 pv 的 dd 命令:
pv source.img | dd of=dest.img bs=4M # 输出: # 2.31G 0:00:15 [ 154MB/s] [=======> ] 1% ETA 0:25:30
可以看到,pv 提供了实时、友好的进度反馈。
pv 是一个非常实用且小巧的命令行工具,它极大地改善了处理长时间运行的数据传输任务的体验,无论是备份、压缩、网络传输还是系统管理,pv 都能让你对任务进度心中有数,是每个 Linux 系统管理者和高级用户工具箱中的必备利器。
