Contents

在Linux中移动文件时显示进度

1. 概述

mv 命令是 Linux 上使用最广泛的文件移动工具。但是,默认情况下,它无法向用户显示进度。有时,当我们移动巨大的文件时,我们需要某种指标来跟踪移动操作的进度。

在本教程中,我们将学习如何通过使用 Linux mv命令的几种替代方法来移动文件并在终端中查看它们的进度。

2. progress

**progress 是一个 UNIX 工具,它使我们能够监控复制或移动操作的进度。**通常,我们会使用mv命令来移动文件或目录,然后在另一个终端中progress

2.1. 安装

progress工具不随发行版一起提供。因此,我们需要使用包管理器(例如yumapt )从发行版的官方存储库中安装进度包。

在 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 是一个高度可配置的复制工具,与cpmv命令相比,它支持很多选项我们不仅可以使用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

您会注意到,类似于cpmv命令,它不打印任何内容,除了错误。让我们使用*-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 脚本的一个很好的起点。