cp复制文件时如何显示传输进度和速度?

Oli*_*nde 457 command-line coreutils

否则,是否有任何替代命令行实用程序可以实现此目的?

Ste*_*zzo 341

虽然cp还没有这个功能,你可以用它pv来做到这一点:

pv my_big_file > backup/my_big_file
Run Code Online (Sandbox Code Playgroud)

注意:此方法将失去文件的权限和所有权。以这种方式复制的文件将与您自己创建的文件具有相同的权限,并且属于您。

在这个例子中,pv基本上只是将文件输出到 stdout*,你可以使用>操作符将其重定向到一个文件。同时,当您执行此操作时,它会将有关进度的信息打印到终端。

这是它的样子:

stefano@ubuntu:~/Data$ pv my_big_file > backup/my_big_file
 138MB 0:00:01 [73.3MB/s] [=================================>] 100% 
Run Code Online (Sandbox Code Playgroud)

你可能需要  安装光伏(或者,键入sudo apt-get install pv) 在您的系统上。


*:技术位

在类 Unix 系统中有三个重要的数据流:stdout(标准输出)、stderr(标准错误)和 stdin(标准输入)。可以这么说,每个程序都具备这三者。该>重定向操作程序输出重定向到一个文件中。没有参数,正如你在上面看到的,>将程序的标准输出重定向到一个文件。cp基本上没有什么比

cat source > destination
Run Code Online (Sandbox Code Playgroud)

(其中cat只是读取一个文件并将其打印到标准输出)。pv就像 cat 一样,但是如果您将它的输出流重定向到其他地方,它会将进度信息打印到 stdout。

看一看man pv以了解更多信息。


另一种选择,如 替代文字执行长这个答案中建议,是使用 rsync 代替:

$ rsync -ah --progress source-file destination-file
sending incremental file list
source-file
        621.22M  57%  283.86MB/s    0:00:01
Run Code Online (Sandbox Code Playgroud)

这将在显示进度的同时保留文件权限/所有权。

  • IMO:`alias cp="rsync -avz"` cp 已过时。 (62认同)
  • 是的,`-z` 应该只用于网络副本;为本地副本压缩和解压缩数据是纯粹的开销。 (16认同)
  • 如果你和我一样,忘记 `pv`,你可以去 cp/fd` 的 `/proc/PID` 和 cp/fdinfo` 的 `/proc/PID` 中窥探进度。(由你来推断速度。)我使用这种技术来观察 `updatedb`。 (11认同)
  • 它可能重要也可能不重要(取决于情况),但是 `pv` 不像 `cp` 那样处理权限......(基于我尝试的一个快速测试:`pv` 没有复制执行位跨..`rsync` 做到了。 (3认同)
  • @MarcoCeppi ,当使用 `rsync` 复制目录时,请确保不要将尾随的 `/` 添加到源路径(或者如果 bash 完成自动将它放在那里,则删除)。否则你会得到与使用 `cp`(或 `gcp`)时不同的结果。 (3认同)
  • @Rodrigo `rsync -avzP` 是您想要使用的。 (2认同)

bar*_*rak 305

没有。请参阅此处了解原因。虽然它做的比你需要的多,但rsync有一个--progress参数。在-a将保持权限等,并-h会是人类可读。

rsync -ah --progress source destination
Run Code Online (Sandbox Code Playgroud)

输出将如下所示:

Pictures/1.jpg
      2.13M 100%    2.28MB/s    0:00:00 (xfr#5898, to-chk=1/5905)
Pictures/2.jpg
      1.68M 100%    1.76MB/s    0:00:00 (xfr#5899, to-chk=0/5905)
Run Code Online (Sandbox Code Playgroud)

  • 这在当前的 Ubuntu (14.10) 中非常有效。它还支持`-r` 标志来递归目录。它甚至可以作为 cp 的直接替代别名:`alias cp="rsync -ah --progress"` (15认同)
  • @bartekbrak 感谢分享。我目前在 macOS 10.12.x 上运行 rsync 3.1.2 的自制版本,并且使用 `--progress` 让我头晕目眩地看着终端中的所有输出显示。所以那些来自 AOL 关键字搜索的人,`rsync -ah --info=progress2 [source] [destination]` 以更理智的 ‍⚕️ 方式呈现输出,恕我直言。 (14认同)
  • @Raphael,真的,这就是为什么你应该使用 `--info=progress2` 而不是 `--progress`,正如@ipatch 在 [他们的评论](https://askubuntu.com/questions/17275/how-to -show-the-transfer-progress-and-speed-when-copying-files-with-cp#comment1638393_201250) (11认同)
  • 我比 pv 更喜欢这个替代方案,特别是因为 rsync 是标准安装的一部分 (7认同)
  • 不幸的是,在复制许多小文件时,输出并不是很有帮助。 (5认同)
  • 我的上帝!很难找到这个信息!从上面使用 `--info=progress2` 会得到一个非常好的输出,如下所示:`2.21G 99% 4.15MB/s 0:08:26 (xfr#7155, ir-chk=3129/10762)`。 (2认同)

小智 102

如果您想查看您的文件是否正确传输,您可以使用它gcpgcp就像 cp 一样,但默认情况下会为您提供一个进度条,以便您可以查看正在复制的内容。正如该程序的wiki 所述gcp有几个有用的功能,例如

  • 转移进展指示
  • 出错时连续复制(跳到下一个文件)
  • 复制状态记录:gcp 记录其所有操作,以便知道哪些文件已成功复制
  • 名称修改以处理目标文件系统限制(例如删除 FAT 上不兼容的字符“*”或“?”)

但是,即使在使用该工具时进度条已达到 100%,您也必须等到终端提示重新出现后才能安全移除媒体,以确保传输过程已成功完成。

gcp用于复制文件并具有诸如--preserve可以保留各种属性和权限以及--recursive可以复制整个目录之类的选项。有关其选项的更多信息可以通过输入man gcp或转至在线 Ubuntu 联机帮助页找到此站点上还提供教程。

gcp从存储库安装

sudo apt-get install gcp
Run Code Online (Sandbox Code Playgroud)

注意:在 Ubuntu 12.10 中,新的自动挂载点是,例如,/media/user/usbdisk

您可以通过输入将文件复制到您的媒体

gcp /home/mike/file.mp4 /media/usb
Run Code Online (Sandbox Code Playgroud)

并将文件夹复制到您的媒体

gcp -rv ~/Podcasts /media/Mik2
Run Code Online (Sandbox Code Playgroud)

gcp带有进度条的示例输出:

gcp ~/Videos_incIplayer/mars.flv /media/Mik2
Copying 168.57 MiB 100% |########################################################|   7.98 M/s Time: 00:00:22
Run Code Online (Sandbox Code Playgroud)

您当然可以指定多个文件或文件夹以复制到您的磁盘,并且man gcp.

  • 通过 ssh 出现错误`dbus.exceptions.DBusException: org.freedesktop.DBus.Error.NotSupported: Unable to autolaunch a dbus-daemon without a $DISPLAY for X11` (5认同)
  • 如果你在机器上打开了 X11 显示器,你可以在启动 gcp 之前设置 `export DISPLAY=:0.0`。如果机器是无头的,那么您必须将 xsession 启动到虚拟帧缓冲区或其他东西中,此时您可能应该寻找另一个程序 (3认同)
  • `gcp` 相当不错,但 DBUS/X 的要求很奇怪。我通过使用 ssh 转发通过 SSH 处理了这个问题:`ssh -X user@host` 并且允许我运行它。 (3认同)
  • 我不推荐 gcp,1.它没有维护。2. 它无法处理符号链接、硬链接等。 3. 它无法处理稀疏文件。 (2认同)

小智 88

为了这个确切的目的,我对使用 cURL 感到很兴奋。手册页列出了受支持的“文件”协议,因此只需像 URL 中的任何其他协议一样使用它:

curl -o destination FILE://source
Run Code Online (Sandbox Code Playgroud)

速度、进度、剩余时间等 - 全部采用熟悉的格式。

  • 太棒了,这必须是一个必须知道的黑客! (9认同)
  • 这可能具有[相同的缺点](https://askubuntu.com/questions/17275/how-to-show-the-transfer-progress-and-speed-when-copying-files-with-cp#comment18577_17279) `pv`,它不会保存权限。 (5认同)
  • `-O`(大写 O)使用源文件名,而不必写入目标文件名 (3认同)
  • 这在禁止安装新工具和 rsync 不可用的环境中尤其有用。 (2认同)
  • 甜的!有什么方法可以使这个目录工作? (2认同)

小智 40

progress存储库中有一个工具可以检查各种不同的命令并显示它们的进度信息。

使用命令安装

sudo apt-get install progress
Run Code Online (Sandbox Code Playgroud)

这个工具可以这样使用:

cp bigfile newfile & progress -mp $!
Run Code Online (Sandbox Code Playgroud)

输出:

[11471] cp /media/Backup/Downloads/FILENAME.file 
        29.9% (24.2 MiB / 16 MiB)
Run Code Online (Sandbox Code Playgroud)

  • 这是我认为 2019 年最新的答案。 (3认同)
  • `progress` 对于一般脚本编写没有用,仅在 `watch` 上下文中有用:a) 它需要全屏 `tty`,并且失败并显示 `Error openingterminal:unknown.`。因此,您无法向管道报告进度以在 CGI 环境中显示进度。b) 现代 shell 不会让僵尸存活足够长的时间,从而为其他进程释放 PID。因此,可能存在竞争条件,其中“progress”可能会监视错误的进程(即“progress”是通过 NFS 加载的)。c) 它无法监视诸如“睡眠”之类的事情,而这可以通过“strace”或“dtrace”以及一些额外的脚本来实现。 (2认同)

Ubu*_*ist 35

虽然它不显示速度,但在复制多个文件时,-vcp命令的选项将为您提供进度信息。例如

cp -rv old-directory new-directory
Run Code Online (Sandbox Code Playgroud)

  • 进度信息?这只是详细的输出。要提供进度信息,您现在至少需要知道需要复制多少个文件,甚至哪些文件。 (13认同)
  • 它显示了它所在的文件,这在要求不高的情况下就足够了。 (3认同)

小智 20

内核知道大部分数据,例如速度,通常还有百分比。现代内核通过他们的 /proc 文件系统公开这一点。

来自https://github.com/jnweiger/showspeed 的showspeed使用该信息。它可以附加到已经运行的程序并提供如下定期更新:

$ dd if=bigfile of=/tmp/otherbigfile &
$ showspeed dd
dd looks like a process name. pid=4417 matches av0=dd.
p/4417/fd/0r /home/jw/bigfile 113MB/s (12%, 2.3GB)  9m:35
p/4417/fd/1w /tmp/otherbigfile 182MB/s (2.6GB)
p/4417/fd/0r /home/jw/bigfile 285MB/s (15%, 3.0GB)  8m:08
p/4417/fd/0r /home/jw/bigfile 115MB/s (16%, 3.2GB)  8m:01
p/4417/fd/0r /home/jw/bigfile 107MB/s (17%, 3.4GB)  7m:39
p/4417/fd/1w /tmp/otherbigfile 104MB/s (3.5GB)
p/4417/fd/0r /home/jw/bigfile 139MB/s (19%, 3.7GB)  7m:37
p/4417/fd/0r /home/jw/bigfile 116MB/s (20%, 3.9GB)  7m:18
p/4417/fd/1w /tmp/otherbigfile  67MB/s (4.0GB)
p/4417/fd/1w /tmp/otherbigfile 100MB/s (4.1GB)
...
Run Code Online (Sandbox Code Playgroud)


小智 13

虽然pv可以处理本地cp任务,使用ddwithpv可以处理本地 ( cp) 和远程 ( scp) 任务。

dd if=path/to/source.mkv | pv | dd of=path/to/dest.mkv
Run Code Online (Sandbox Code Playgroud)

请确保path/to/dest.mkv出口touch path/to/dest.mkv

这可以显示进度,但如果您想要百分比信息,

dd if=path/to/source.mkv | pv -s 100M | dd of=path/to/dest.mkv
Run Code Online (Sandbox Code Playgroud)

100M源文件的实际大小替换上面的内容。

远程部分来了

虽然scp很难显示当前的进度,但使用ddwithpv是小菜一碟。

ssh onemach@myotherhost dd if=path/to/source.mkv | pv -s 100M | dd of=path/to/dest.mkv
Run Code Online (Sandbox Code Playgroud)

  • 较新的 `dd` 有 `status=progress`:http://askubuntu.com/a/824895/52975 (2认同)

S L*_*ntz 12

如果您有 rsync 3.1 或更高版本 ( rsync --version),您可以在保留权限和所有权的同时复制 (cp -Rpn)、递归目录、“没有破坏”,并显示整体进度(而不仅仅是按文件进度)、复制速率和(非常粗略)估计剩余时间:

sudo rsync -a --info=progress2 --no-i-r /source /destination
Run Code Online (Sandbox Code Playgroud)

请注意,只有在处理您不拥有的目录/文件时才需要 sudo。此外,如果没有--no-i-r,百分比可能会在复制过程中的某个时刻重置为较低的数字。也许更高版本的 rsync 将默认为 no-ir with info=progress2,但它在 3.1.2 的当前版本中没有。

我发现在复制到已经包含文件的目录时,剩余的百分比和时间被严重高估了(例如,当您通常使用 cp -n "no clobber" 时)。


小智 11

有一个名为 cv 的新工具可以找到与正在运行的命令相关的任何描述符并显示进度和速度:https : //github.com/Xfennec/cv

cv -w
Run Code Online (Sandbox Code Playgroud)

输出所有正在运行的 cp、mv 等操作的统计信息

  • 它战争更名为进步。很棒的工具! (2认同)

Gab*_*les 10

这里已经有一些非常好的答案,但这里是我最喜欢的命令,包括我自己对命令的一些修改rsync,以及我最喜欢的选项:

1. watch 'du -hs'(或者,为了更精细:)watch -n 1 'du -sk | awk '\''{printf "%.3f MiB %s\n", $1/1024, $2}'\'''允许您观察目标文件夹的大小增长情况(如果cp已在运行):

如果您已经开始了一个漫长的cp过程并且现在不想停止怎么办?

假设您已经启动了此复制命令:

# recursively copy source_dir_name to destination
cp -r source_dir_name destination
Run Code Online (Sandbox Code Playgroud)

只需打开一个新终端,复制操作已经在进行中,然后运行:

# cd into destination directory
cd path/to/destination/source_dir_name

# Now watch, live, the size of this destination grow!
watch 'du -hs'

# OR (Preferred!) see even more granularity, in X.xxx MiB: 
watch 'du -sk | awk '\''{printf "%.3f MiB %s\n", $1/1024, $2}'\''' 
Run Code Online (Sandbox Code Playgroud)

这将导致watch命令在目标目录中每 2 秒自动运行一次du -hs(或du -sk | awk '{printf "%.3f MiB %s\n", $1/1024, $2}')(默认为watch),因此您可以看到文件夹的大小实时增长!这并没有给你一个完成的百分比,但如果你对你正在复制的内容的大小有一个粗略的了解,它肯定会给你一些值得关注和感觉良好的东西,因为你知道目的地正在增长。以下是手表屏幕上的输出示例:

  1. 命令:watch 'du -hs'

    输出:

    Every 2.0s: du -hs
    
    2.5G    .
    
    Run Code Online (Sandbox Code Playgroud)
  2. 命令:watch 'du -sk | awk '\''{printf "%.3f MiB %s\n", $1/1024, $2}'\'''

    输出:

    Every 2.0s: du -sk | awk '{printf "%.3f MiB %s\n", $1/1024, $2}'
    
    2560.348 MiB .
    
    Run Code Online (Sandbox Code Playgroud)

在上面,您可以看到当前目录 ( ) 的当前大小.为 2.5 GiB,或者更具体地说,在第二种情况下:2560.348 MiB。要watch使用较慢的更新间隔(例如 5 秒),只需添加-n 5watch命令中,如下所示:

watch -n 5 'du -hs'

# OR (preferred, for more granularity)
watch -n 5 'du -sk | awk '\''{printf "%.3f MiB %s\n", $1/1024, $2}'\'''
Run Code Online (Sandbox Code Playgroud)

2.rsync确实最适合这个:

我最喜欢的命令:

# dry-run
time rsync -rah --dry-run --info=progress2 --stats source destination

# real copy (Important! Do a dry run first and read the
# output summary to ensure you're copying what you intend!)
time rsync -rah --info=progress2 --stats source destination
Run Code Online (Sandbox Code Playgroud)

注意:time上述命令前面的部分只是输出最终操作的总运行时间的一个很好的时间摘要。这在任何 Linux 命令之前起作用。

顺便说一句,这是rsync --statsa 的摘要:--dry-run

$ rsync -rah --dry-run --info=progress2 --stats /media/gabriel/cdrom ~/temp
          2.76G 100% 2570.10GB/s    0:00:00 (xfr#3836, to-chk=0/4837)   

Number of files: 4,837 (reg: 3,836, dir: 1,001)
Number of created files: 0
Number of deleted files: 0
Number of regular files transferred: 3,836
Total file size: 2.76G bytes
Total transferred file size: 2.76G bytes
Literal data: 0 bytes
Matched data: 0 bytes
File list size: 0
File list generation time: 0.001 seconds
File list transfer time: 0.000 seconds
Total bytes sent: 123.88K
Total bytes received: 15.54K

sent 123.88K bytes  received 15.54K bytes  278.85K bytes/sec
total size is 2.76G  speedup is 19,792.78 (DRY RUN)
Run Code Online (Sandbox Code Playgroud)

参考:

  1. 我在 ROS 教程中首次记录 type 命令的位置watch -n 5 'du -sk | awk '\''{printf "%.3f MiB %s\n", $1/1024, $2}'\'''我的 ROS.org 教程:从包文件中读取消息

额外阅读:

  1. 我对一些高级rsync用法和内容的长答案:https://superuser.com/questions/1271882/convert-ntfs-partition-to-ext4-how-to-copy-the-data/1464264#1464264
  2. [我的另一个答案] Unix & Linux: 是否可以看到 cp 速度和复制百分比?


Alo*_*dal 9

正如许多人所说,cp 不包含此功能。

只是为了抛出我的 0.02 美元,我通常在琐碎的复制情况下做的事情(即 no -R):

  1. 查看文件有多大并记住

  2. 开始复印

  3. 打开另一个终端

  4. watch ls -lh DIR在目标所在的目录上运行

这可以让我了解目标文件大小的最新信息,而且麻烦最少。

作为不太重要的情况的替代方案,例如递归复制目录,您可以使用watch du -hs DIR查看 DIR 大小的摘要。但是 du 可能需要很长时间来计算,甚至会减慢复制速度,因此您可能希望使用-n INTERVAL参数来观察,以便可以接受权衡。

更新:如果您使用通配符与 watch du 一起使用的命令,例如watch du -hs backup/*,不要忘记引用:

watch "du -hs backup/*"
Run Code Online (Sandbox Code Playgroud)

否则通配符将只扩展一次,当 watch启动时,du 将不会查看新文件/子目录。


Cir*_*郝海东 9

dd status=progress

在 GNU Coreutils 8.24+ (Ubuntu 16.04) 中添加的选项:

dd if=src of=dst status=progress
Run Code Online (Sandbox Code Playgroud)

终端显示一行类型:

462858752 bytes (463 MB, 441 MiB) copied, 38 s, 12,2 MB/s
Run Code Online (Sandbox Code Playgroud)

定期更新。

另请参阅:您如何监控 dd 的进度?


ale*_*ail 5

pv 知道如何观察给定 pid 的文件描述符,无论是 cp 还是其他东西

从文档中:

   (Linux only): Watching file descriptor 3 opened by another process 1234:

          pv -d 1234:3

   (Linux only): Watching all file descriptors used by process 1234:

          pv -d 1234
Run Code Online (Sandbox Code Playgroud)

例子:

md5sum file &
[1] + 1271 suspended
pv -d 1271
417MiB 0:00:17 [12,1MiB/s] [============>                                 ] 29% ETA 0:00:53

$ cp file.mov copy.mov &
[2] 3731
$ pv -d 3731
3:/media/windows/file.mov:  754MiB 0:00:04 [97,2MiB/s] [======================>                       ] 52% ETA 0:00:07
4:/media/windows/copy.mov:  754MiB 0:00:04 [97,3MiB/s] [     <=>                                                                   ] 
Run Code Online (Sandbox Code Playgroud)