在Linux中移动文件时显示进度
1. 概述
mv 命令是 Linux 上使用最广泛的文件移动工具。但是,默认情况下,它无法向用户显示进度。有时,当我们移动巨大的文件时,我们需要某种指标来跟踪移动操作的进度。
在本教程中,我们将学习如何通过使用 Linux mv命令的几种替代方法来移动文件并在终端中查看它们的进度。
2. progress
**progress 是一个 UNIX 工具,它使我们能够监控复制或移动操作的进度。**通常,我们会使用mv命令来移动文件或目录,然后在另一个终端中progress
2.1. 安装
progress工具不随发行版一起提供。因此,我们需要使用包管理器(例如yum 或apt )从发行版的官方存储库中安装进度包。
在 Debian 和 Ubuntu 上,执行以下操作:
$ apt install progress
在 Fedora、CentOS 和 RHEL 上:
$ yum install progress
关于 Arch 及其衍生产品:
$ pacman -S progress
安装完成后,让我们验证一下:
$ progress -v
progress version 0.16
2.2. 用法
现在,作为示例,我们将*~/.cache目录移动到/tmp*。然后,我们将使用带有一些有用选项的progress命令。所以,让我们开始移动目录:
$ mv ~/.cache /tmp
众所周知, 默认情况下, mv命令不会打印任何内容,除非出现错误。我们将保持它完好无损并打开另一个终端实例,我们将在其中监视命令的进度。因此,让我们打开另一个终端实例并输入progress命令:
$ progress
[ 5187] mv /home/hey/.cache/paru/clone/android-studio/android-studio-2020.3.1.26-linux.tar.gz
0.0% (0 / 935.2 MiB)
**该命令将打印出当前状态的进度并立即退出。如果我们需要在 shell 脚本中使用progress命令,这很有用。*另一方面,如果我们想监控进度,我们需要使用–monitor或-m*选项:
$ progress -mw
-w或*–wait选项启用 ETA 。运行命令后,我们将看到mv*命令的实时进度:
$ [ 5251] mv /home/hey/.cache/paru/clone/amdgpu-pro-installer/amdgpu-pro-21.30-1290604-ubuntu-20.04.tar.xz
35.31% (241.3 / 683.2 MiB) 0/s
如果我们有多个mv操作,我们还可以提供*–pid*选项:
$ progress -mw --pid $(pgrep mv)
3. rsync
rsync 是一个高度可配置的复制工具,与cp和mv命令相比,它支持很多选项我们不仅可以使用rsync在本地复制/移动文件,还可以远程 。默认情况下,rsync不会向我们显示任何进度。幸运的是,有一个*-P*选项可以为它复制的每个文件显示一个进度指示器。
3.1. 安装
大多数完整的发行版都预装了rsync 。如果我们在一个最小的发行版上,我们可以从我们的发行版的官方存储库安装它。
在 Ubuntu 衍生产品上:
$ apt install rsync
在 Fedora、CentOS 和 RHEL 上:
$ yum install rsync
关于 Arch 及其衍生产品:
$ pacman -S rsync
安装后,让我们验证一下:
$ rsync -V
rsync version v3.2.3 protocol version 31
Copyright (C) 1996-2020 by Andrew Tridgell, Wayne Davison, and others.
3.2. 基本用法
使用rsync复制文件的基本语法是:
$ rsync [OPTIONS] [SOURCE...] [DESTINATION]
我们可以根据需要指定任意数量的来源。让我们使用*-r或–recursive选项使用rsync*复制我们的目录:
$ rsync -r ~/.cache/* /tmp/cache
您会注意到,类似于cp或mv命令,它不打印任何内容,除了错误。让我们使用*-P*选项启用进度条:
$ rsync -r -P ~/cache/* /tmp/cache
chromium/Default/Cache/Cache_Data/2d0111cfb1b11d58_0
6,177 100% 60.32kB/s 0:00:00 (xfr#811, ir-chk=1565/2529)
chromium/Default/Cache/Cache_Data/2d152dfa21362cbf_0
7,724 100% 75.43kB/s 0:00:00 (xfr#812, ir-chk=1564/2529)
chromium/Default/Cache/Cache_Data/2d1e7c47b097a512_0
9,468 100% 92.46kB/s 0:00:00 (xfr#813, ir-chk=1563/2529)
chromium/Default/Cache/Cache_Data/2d490754d7b0a757_0
.
.
.
运行命令后,您会注意到rsync会打印每个文件的进度。现在,一切都很好,但它仍然没有删除源文件。默认情况下,rsync不会将文件从一个位置移动到另一个位置——而是复制它们。幸运的是,我们还有–remove-source-files*选项,一旦源文件被完全复制,它将删除它们*:
$ rsync -aP --remove-source-files ~/.cache /tmp/cache
3.3. 更好的方法
尽管*–remove-source-files选项确实删除了文件,但它不会从源中删除目录。因此,为了使rsync模拟mv命令,我们将编写一个非常简单的bash*脚本,该脚本将处理多个源并在复制后删除源目录和文件。
脚本使用语法类似于我们使用rsync的方式。首先,我们将提供一个或多个输入文件和目标目录作为最后一个参数。然后,复制完成后,我们将完全删除源文件和目录:
#!/bin/bash
# Safety check
[ "$#" -eq 0 ] && "No input files" && exit 1
rsync -aP --remove-source-files "$@" && rm -rf "${@:1:$#-1}"
**“ $@ ”运算符将扩展到位置参数,在我们的例子中将是源和目的地。**第二个命令递归地删除源。“${@:1:$#-1}” 表达式基本上将扩展为提供的参数减去最后一个参数,即我们的目标目录。
**“&&”后面的命令只有在rsync命令成功退出时才会运行。**否则,文件将被保留而不被删除。完成后,让我们在脚本可执行后对其进行测试:
$ rsmv ~/.cache/ctrlp /tmp/cache
mru/
mru/cache.txt
749 100% 0.00kB/s 0:00:00 (xfr#1, to-chk=0/2)
4. 管道查看器
Pipe Viewer 或pv 是我们用来监控通过管道传输数据的进度的工具。**在我们只有一个大文件想要移动的情况下,它很有用,同时监控它的进度。**虽然它不适用于多个文件,但我们可以编写一个脚本来处理多个源。
4.1. 安装
在大多数主要发行版上,已经安装了pv。我们也可以从我们的官方包存储库安装它。
在 Debian 和 Ubuntu 衍生产品上,执行以下操作:
# apt install pv
在 Fedora、CentOS 和 RHEL 上,执行以下操作:
# yum install pv
在 Arch-derivatives 上,执行以下操作:
# pacman -S pv
安装后,我们将对其进行验证:
$ pv -V
pv 1.6.20 - Copyright 2015 Andrew Wood <[[email protected]](/cdn_cgi/l/email_protection)>
4.2. 用法
使用pv非常简单。我们可以将pv命令放在管道操作之前,也可以将它放在两个命令之间:
$ pv INPUT > OUTPUT
$ CMD | pv | CMD
$ CMD | pv [OPTIONS] > OUTPUT
例如,让我们将一个文件的内容通过管道传输到另一个文件中:
$ pv amdgpu-pro-21.30.tar.xz > /tmp/amdgpu-pro.tar.xz
683MiB 0:00:01 [ 494MiB/s] [==================================================================================>] 100%
现在,这很好,但我们在源目录中仍然有原始的amdgpu-pro-21.30.tar.xz文件。出于这个原因,我们将使用mv命令并让pv为我们测量进度。mv命令有一个*-v或–verbose选项,用于打印每个移动文件的反馈。 **我们将使用mv的-v选项作为pv*命令找出进度**的线索:
$ mv source_dir dest_dir | pv -l -s $(find source_dir | wc -l) > /tmp/log
让我们分解一下:
- pv命令的*-l*选项将计算行数而不是字节数
- -s选项指定正在传输的数据的大小,以便pv可以估计进度;默认情况下,这是以字节为单位指定的,但由于我们使用了*-l*选项,它是文件数
我们通过指定给*-s*选项的find 命令找到估计的文件总数。这样,pv现在将随着更多文件的移动而更新进度。
虽然这个解决方案不像前两个那样优雅,但它应该是编写可定制的 shell 脚本的一个很好的起点。