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


Answers:


249

虽然cp没有此功能,但您可以使用此功能pv

pv my_big_file > backup/my_big_file

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

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

看起来是这样的:

stefano@ubuntu:~/Data$ pv my_big_file > backup/my_big_file
 138MB 0:00:01 [73.3MB/s] [=================================>] 100% 

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


*:技术位

在类Unix系统中,有三个重要的数据流:stdout(标准输出),stderr(标准错误)和stdin(标准输入)。可以这么说,每个程序都有这三个。该>重定向操作程序输出重定向到一个文件中。如上所示,没有参数的情况下,>会将程序的标准输出重定向到文件。cp基本上没有比这更好的了

cat source > destination

cat仅读取文件并将其打印到stdout)。pv就像cat,但是如果将它的输出流重定向到其他地方,它将打印进度信息到stdout。

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


正如替代文字DoR此答案中建议的那样,另一种选择是使用rsync代替:

$ rsync -ah --progress source-file destination-file
sending incremental file list
source-file
        621.22M  57%  283.86MB/s    0:00:01

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


3
它可能会或可能不会有显著(视情况而定),但pv权限以同样的方式不处理的cp呢...(基于一个简单的测试我想:pv没碰到过..复制执行位rsync。没有
彼得.O 2010年

45
IMO:alias cp="rsync -avz"cp已过时。
Marco Ceppi

11
如果您像我一样,并且忘记了pv,可以偷窥/proc/PID of cp/fd/proc/PID of cp/fdinfo确定进度。(由您来推断速度。)我使用这种技术进行观看updatedb
塔纳托斯

11
是的,-z应该只用于网络副本;压缩和解压缩本地副本的数据纯属开销。
马修(Matthew)

3
@MarcoCeppi,在复制目录时,请rsync确保不要在/源路径中添加尾随(或删除,如果bash 补全会自动将其放在此处)。否则,您将获得与使用cp(或gcp)时不同的结果。
Piotr Findeisen

185

没有。看看这里为什么。尽管它做的比您需要的要多,但rsync有一个--progress参数。在-a将保持权限等,并-h会是人类可读。

rsync -ah --progress source destination

输出将如下所示:

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)

4
这在当前的Ubuntu(14.10)中效果很好。它还支持-r递归目录的标志。它甚至可以别名为cp的直接替代品:alias cp="rsync -ah --progress"
rustyx 2014年

1
在OS X上可以正常工作,并且可以使用系统附带的工具。
伊万X

3
我比PV更喜欢这种替代方法,特别是因为rsync是标准安装的一部分
Joao Costa

1
@bartekbrak感谢您的分享。我目前在运行rsync 3.1.2的自制版本的macOS 10.12.x上使用,--progress使我的头部旋转🙃观看终端中的所有输出显示。因此,那些来自AOL关键字搜索的 rsync -ah --info=progress2 [source] [destination] 内容以恕我直言的方式呈现输出。
ipatch

2
不幸的是,在复制许多小文件时,输出不是很有帮助。
拉斐尔

89

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

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

但是,即使在使用该工具时进度条达到100%的情况下,也必须等到终端提示再次出现后,才能安全删除介质,以确保传输过程已成功完成。

gcp用于复制文件,并具有诸如的选项,--preserve以便可以保留各种属性和权限,并--recursive可以复制整个目录。有关其选项的更多信息,可通过进入man gcp在线访问Ubuntu手册页找到该站点上也提供教程。

gcp从存储库安装

sudo apt-get install gcp

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

您可以通过输入以下命令将文件复制到媒体中

gcp /home/mike/file.mp4 /media/usb

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

gcp -rv ~/Podcasts /media/Mik2

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

gcp ~/Videos_incIplayer/mars.flv /media/Mik2
Copying 168.57 MiB 100% |########################################################|   7.98 M/s Time: 00:00:22

当然,您可以指定多个文件或文件夹以复制到磁盘上,并且还介绍了许多其他选项man gcp


4
在ssh上收到了错误dbus.exceptions.DBusException: org.freedesktop.DBus.Error.NotSupported: Unable to autolaunch a dbus-daemon without a $DISPLAY for X11
消息-msa7,2016年

3
如果您在计算机上打开了X11显示屏,则可以export DISPLAY=:0.0在启动gcp之前进行设置。如果机器没有头,那么您必须将xsession启动到虚拟帧缓冲区之类的东西,
那时候

2
gcp相当不错,但DBUS / X要求却很奇怪。我使用ssh转发通过SSH处理了此问题:ssh -X user@host这使我可以运行它。
奥利(Oli)

68

我完全不愿意使用cURL来达到这个目的。手册页列出了受支持的“ FILE”协议,因此就像在URL中使用其他协议一样使用它:

curl -o destination FILE://source

速度,进度,剩余时间等-一切都以熟悉的格式呈现。


1
这在禁止安装新工具且rsync不可用的环境中尤其有用。

5
太棒了,这一定是一个必不可少的技巧!
ionreflex

好答案!聪明!
9301293

这大概有同样的缺点,因为pv,它不会保存权限。
Ploni '18

1
甜!有什么办法可以使目录工作?
约瑟夫·拉杰夫·莫莎

28

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

cp -rv old-directory new-directory

10
进度信息?这只是冗长的输出。要提供进度信息,您至少现在需要复制多少文件,甚至需要复制哪些文件。
朱利安·F·韦纳特

它显示了文件所在的文件,在要求不高的情况下就足够了。
Gringo Suave

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)
...

好东西。但是如何计算出百分比呢?我猜只是在文件以只读方式打开的情况下?在分散访问的情况下,它可能不起作用。
j_kubik 2014年

1
在这种情况下,您也可以使用另一个终端运行pkill -USR1 dddd显示其状态,另一种选择是watch -n 1 pkill -USR1 dd使其定期(每秒)显示其进度。
Yaron

对。许多工具都有内置的方式来报告一段时间内的统计信息。dd也不例外。现代实现具有status = progess选项。Showspeed是一种经典的Unix风格的“一种工具,一种目的”,就像光伏一样。但是它有不同的用例:想像一下通过ghostscript抽取文件的杯子,或者您想知道正在进行的cp或tar的ETA。几个小时后可能已经完成了95%,您可能不想仅添加pv就重新启动。Showspeed仅样本寻找位置。
尔根·魏格特18'Apr

18

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

使用命令安装

sudo apt-get install progress

该工具可以这样使用:

cp bigfile newfile & progress -mp $!

输出:

[11471] cp /media/Backup/Downloads/FILENAME.file 
        29.9% (24.2 MiB / 16 MiB)

12

虽然pv可以处理本地cp的任务,使用dd具有pv能处理本地(cp)和远程(scp)的任务。

dd if=path/to/source.mkv | pv | dd of=path/to/dest.mkv

请确保path/to/dest.mkv通过touch path/to/dest.mkv

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

dd if=path/to/source.mkv | pv -s 100M | dd of=path/to/dest.mkv

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

远程部分到了

虽然scp几乎无法显示当前的进度,但使用ddwith pv却是小菜一碟。

ssh onemach@myotherhost dd if=path/to/source.mkv | pv -s 100M | dd of=path/to/dest.mkv


11

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

cv -w

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


watch cv -q更整洁
nwgat 2015年

它仅显示单个文件的进度,并且确实意识到a是否以cp递归方式复制目录。
Flimm

1
它把战争更名为进步。很棒的工具!
sebastian

7

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

只是丢下我的0.02美元,这是我通常在琐碎的复印情况下所做的工作(即,否-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/*"

否则,当监视开始时,通配符将仅扩展一次,因此du将不会查看新文件/子目录。


但是,没有回答“速度”部分……
Alois Mahdal 2012年

7

dd status=progress

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

dd if=src of=dst status=progress

终端显示以下类型的行:

462858752 bytes (463 MB, 441 MiB) copied, 38 s, 12,2 MB/s

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


1
您的意思是:stdout是字符和vt100转义序列的流,使您的终端显示定期更新的行;)。stdout始终是字节流,与它的显示方式无关(除非应用程序可以知道它当前是否已连接到终端...)
masterxilo

@masterxilo newbs不在乎,专家会知道;-)呵呵
Ciro Santilli新疆改造中心法轮功六四事件

好吧,我认为陈述事实总是一件好事,也许遗漏了一些细节,但决不要使读者产生错误的思维模式。如果您说“ stdout是(定期更新的)行”,则似乎您是在说stdout是一个可变内存块,不是。即使对于新手来说,这一点也很重要。
masterxilo

6

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

sudo rsync -a --info=progress2 --no-i-r /source /destination

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

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


3

使用shell脚本:

#!/bin/sh
cp_p()
{
   strace -q -ewrite cp -- "${1}" "${2}" 2>&1 \
      | awk '{
        count += $NF
            if (count % 10 == 0) {
               percent = count / total_size * 100
               printf "%3d%% [", percent
               for (i=0;i<=percent;i++)
                  printf "="
               printf ">"
               for (i=percent;i<100;i++)
                  printf " "
               printf "]\r"
            }
         }
         END { print "" }' total_size=$(stat -c '%s' "${1}") count=0
}

看起来像:

% cp_p /home/echox/foo.dat /home/echox/bar.dat
66% [===============================>                      ]

资源


3

根据您要执行的操作,mc可能是Midnight Commander()。我很惊讶尚未被提及。

诸如pv或之rsync类的工具可以很好地显示一个大文件的传输进度,但是当涉及到复制整个目录/树时,请mc计算大小,然后很好地显示进度。另外,它在大多数系统上都是开箱即用的。


2
“它在大多数系统上都是开箱即用的。” ...不在任何默认的Ubuntu安装上。
muru

1

保留属性的另一个选择是(如果source将在中创建文件夹destination

tar -c source | pv -e -t -p -r | tar -C destination  -x

希望对某人有用。要估算传输时间,可以do -s source提前进行并将其作为-s <size>参数传递给pv


-f -是多余的。tar的默认输出c和输入为xstdout和stdin。
muru 18-10-17,16

可能取决于OS / tar版本吗?我知道这是一个Ubuntu网站,但对其他操作系统所有者(如macOS)可能很有用
ciekawy

1
不。所有合理的实现(包括macOS使用的libarchive的tar)都具有这种行为。
muru 18-10-17

刚刚在macOS上进行了验证,您的建议完全有效-我已经更新了答案。谢谢!
ciekawy

0

您可以使用任何程序进行复制。同时,您可以启动sudo iotop并查看实际的磁盘读/写速度,但是没有任何进展。


0

在下面的git仓库中检查progress_bar的源代码

https://github.com/Kiran-Bose/supreme

也可以尝试定制bash脚本包至上

下载deb文件并安装在基于debian的发行版中,或下载源文件,进行修改并用于其他发行版

功能概述

(1)打开应用程序---- Firefox ----计算器----设置

(2)管理文件----搜索----导航----快速访问

            |----Select File(s)
            |----Inverse Selection
            |----Make directory
            |----Make file
                                          |----Open
                                          |----Copy
                                          |----Move
                                          |----Delete
                                          |----Rename
                                          |----Send to Device
                                          |----Properties

(3)管理电话-从电话中移动/复制-移动/复制到电话-同步文件夹

(4)管理USB ----从USB移动/复制----移动/复制到USB


0

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

例:

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] [     <=>                                                                   ] 
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.