Contents

在Linux中ZIP命令简介

1. 概述

在本教程中,我们将了解 Linux 中的zip命令行工具。

2. zip

zip 命令是 Linux 中的命令行工具,它允许我们创建文件和目录的存档。除此之外,它还提供了多种操作档案的功能。

2.1. 安装

要在基于 Debian 的 Linux 中安装 zip命令行工具,我们可以使用包管理器apt-get

$ sudo apt-get update -qq
$ sudo apt-get install -y zip

此外,我们可以使用包管理器yum 在基于 RHEL 的 Linux 中安装 zip命令行工具:

$ sudo yum update -qq
$ sudo yum install -y zip

2.2. 一般语法

一般我们可以将zip命令表达为:

$ zip [options] [zipfile [files...]] [-xi list]

首先,zip命令接受一个可选标志列表。这些标志用作运行命令的不同选项。然后,参数zipfile指定存档的文件名。接下来, files参数指定文件名列表。

最后,可选标志*-xi*定义排除和包含过滤器。此外,必须在命令末尾定义这组标志。

2.3. 基本用法

zip命令最简单的用例之一是创建一些文件的存档。例如,我们可以使用 zip创建包含文件credentials.txt和 statement.txt的存档important-backup.zip

$ zip important-backup.zip credentials.txt statement.txt
  adding: credentials.txt (stored 0%)
  adding: statement.txt (stored 0%)

3. 列出档案内容而不解档

有时,我们可能只想看一眼档案的内容而不解压它。这可以使用zipinfounzip 命令轻松实现,这两个命令都随zip安装一起提供。

要使用zipinfo查看存档的内容,我们可以使用存档文件名作为其唯一参数运行命令:

$ zipinfo important-backup.zip
Archive:  important-backup.zip
Zip file size: 347 bytes, number of entries: 2
-rw-r--r--  3.0 unx        8 tx stor 21-May-03 11:22 credentials.txt
-rw-r--r--  3.0 unx        5 tx stor 21-May-03 11:22 statement.txt
2 files, 13 bytes uncompressed, 13 bytes compressed:  0.0%

同样,我们可以使用unzip命令直接列出压缩包的内容:

$ unzip -l important-backup.zip
Archive:  important-backup.zip
##   Length      Date    Time    Name
        8  2021-05-03 11:22   credentials.txt
##         5  2021-05-03 11:22   statement.txt
       13                     2 files

使用标志 -l,该命令不会提取存档,而只会列出其内容。

4. 在不解压缩的情况下从存档中删除文件

要在不解压缩的情况下删除存档中的某些条目,我们可以将标志*-d*传递给 zip命令。例如,我们可以 使用zip -dimportant-backup.zip存档中删除statement.txt文件:

$ zip -d important-backup.zip statement.txt
deleting: statement.txt

我们来看看 命令返回后important-backup.zip压缩包的内容:

$ zipinfo important-backup.zip
Archive:  important-backup.zip
Zip file size: 188 bytes, number of entries: 1
-rw-r--r--  3.0 unx        8 tx stor 21-May-03 11:22 credentials.txt
1 file, 8 bytes uncompressed, 8 bytes compressed:  0.0%

正如我们所见,statement.txt已从存档中删除,而无需先提取存档的内容。

5.附加到现有档案

zip 命令提供了使用*-g*标志将附加条目附加到现有存档的选项。

例如,假设我们有一个现有的存档文件important-backup.zip

$ zipinfo important-backup.zip
Archive:  important-backup.zip
Zip file size: 188 bytes, number of entries: 1
-rw-r--r--  3.0 unx        8 tx stor 21-May-03 11:22 credentials.txt

我们可以通过将标志 -g传递给zip命令,将两个条目添加到important-backup.zip存档中:

$ zip -g important-backup.zip bank-accounts.txt customer-details.txt
  adding: bank-accounts.txt (stored 0%)
  adding: customer-details.txt (stored 0%)

在上面的示例中,我们将新条目bank-accounts.txt和 customer-details.txt添加到 important-backup.zip中。现在,存档将总共包含三个条目:

$ zipinfo important-backup.zip
Archive:  important-backup.zip
Zip file size: 551 bytes, number of entries: 3
-rw-r--r--  3.0 unx        8 tx stor 21-May-03 11:22 credentials.txt
-rw-r--r--  3.0 unx       17 tx stor 21-May-03 11:49 bank-accounts.txt
-rw-r--r--  3.0 unx       16 tx stor 21-May-03 11:49 customer-details.txt
3 files, 41 bytes uncompressed, 41 bytes compressed:  0.0%

如果指定的归档文件不存在,zip命令将创建它

让我们 使用不存在的存档文件名运行zip -g命令:

$ zip -g total-new-archive.zip bank-accounts.txt customer-details.txt
        zip warning: total-new-archive.zip not found or empty
  adding: bank-accounts.txt (stored 0%)
  adding: customer-details.txt (stored 0%)

我们可以看到 zip命令打印了一条警告,告诉我们找不到存档total-new-archive.zip 。尽管如此,它还是创建了bank-accounts.txt和 customer-details.txt并将其放入存档中。

6. 加密档案

zip命令 允许我们使用标志*-e*加密存档。使用标志 -e,该命令将要求输入密码作为加密存档的加密密钥。

让我们创建并加密存档文件 encrypted-backup.zip

$ zip -e encrypted-backup.zip bank-accounts.txt credentials.txt
Enter password:
Verify password:
  adding: bank-accounts.txt (stored 0%)
  adding: credentials.txt (stored 0%)

使用标志 -e,该命令现在将提示我们输入用作加密密钥的密码。

如果我们现在尝试unzip档案,它会要求输入密码来解压缩它:

$ unzip encrypted-backup.zip
Archive:  encrypted-backup.zip
[encrypted-backup.zip] bank-accounts.txt password:

但是,我们仍然可以在不知道密码的情况下使用zipinfounzip 等工具列出加密存档的内容

$ zipinfo encrypted-backup.zip
Archive:  encrypted-backup.zip
##   Length      Date    Time    Name
       17  2021-05-03 11:49   bank-accounts.txt
##         8  2021-05-03 11:22   credentials.txt
       25                     2 files

如我们所见,当我们尝试阅读其内容列表时,它不会提示我们输入密码。

7. 递归遍历子目录

默认情况下,zip命令不会递归地归档目录。通过使用标志-rzip将递归地遍历子目录并归档它们的文件**。 例如,假设我们有一个包含一些秘密文件的目录prod-secret

$ ls prod-secret
kafka-passwd.secret  mongo-passwd.secret  mysql-passwd.secret

要创建整个prod-secret目录的存档,我们可以运行带有标志 -rzip命令:

$ zip -r prod-secret.zip prod-secret
  adding: prod-secret/ (stored 0%)
  adding: prod-secret/mysql-passwd.secret (stored 0%)
  adding: prod-secret/mongo-passwd.secret (stored 0%)
  adding: prod-secret/kafka-passwd.secret (stored 0%)

运行带有选项*-r*的命令可确保目录中的文件也包含在内。

但是,zip命令将忽略prod-secret目录中没有标志*-r*的文件:

$ zip prod-secret prod-secret
  adding: prod-secret/ (stored 0%)

8. 包含和排除文件模式

zip命令允许我们构建过滤器以包含或排除文件。此外,这些过滤器是用glob pattern 定义的。此外,我们可以在创建、删除或刷新模式下使用这些过滤器。

假设我们在以下目录中工作:

$ tree -a
.
|-- .git
|   |-- HEAD
|   |-- branch
|   `-- tag
|-- credentials.txt
|-- customer-details.txt
`-- prod-secret
    |-- .git
    |   |-- HEAD
    |   `-- branch
    |-- kafka-passwd.secret
    |-- mongo-passwd.secret
    `-- mysql-passwd.secret
3 directories, 10 files

使用 tree 命令,我们以图形形式显示目录结构。我们可以看到,当前目录下有一个*.git*子文件夹,prod-secret目录下也有一个。

8.1. 包括与模式匹配的文件和文件夹

使用标志-i,我们可以创建一个包含过滤器**。当我们定义包含过滤器时,zip命令将只考虑与过滤器模式匹配的文件。

让我们创建一个 仅包含 .git 子文件夹的存档only-git.zip

$ zip -r only-git.zip . -i *.git*
  adding: prod-secret/.git/ (stored 0%)
  adding: prod-secret/.git/branch (stored 0%)
  adding: prod-secret/.git/HEAD (stored 0%)
  adding: .git/ (stored 0%)
  adding: .git/tag (stored 0%)
  adding: .git/branch (stored 0%)
  adding: .git/HEAD (stored 0%)

从输出中,我们可以看到 zip命令仅归档与 glob 匹配的文件夹和文件。

8.2. 排除与模式匹配的文件和文件夹

要创建排除过滤器,我们可以使用标志-x*后跟一个 glob pattern*。使用排除过滤器,zip将排除与模式匹配的文件。特别是,我们可以使用 zip -x创建一个排除*.git*文件夹的存档:

$ zip -r no-git.zip . -x *.git*
  adding: prod-secret/ (stored 0%)
  adding: prod-secret/mysql-passwd.secret (stored 0%)
  adding: prod-secret/mongo-passwd.secret (stored 0%)
  adding: prod-secret/kafka-passwd.secret (stored 0%)
  adding: customer-details.txt (stored 0%)
  adding: credentials.txt (stored 0%)

从输出中我们可以观察到,该命令没有将任何一个*.git文件夹添加到存档no-git.zip*中。

8.3. 关于路径评估的注意事项

每当zip评估包含和排除的文件和目录路径时,它总是评估完整的相对路径。换句话说,如果 glob 模式是*.git\ ,生成的存档将为空:

$ zip -r only-git.zip . -i .git*
        zip warning: zip file empty

这是因为当前工作目录中*.git*文件夹的确切路径是 ./.git/,它与 glob 模式 .git* 不匹配。同样, prod-secret目录中 .git 文件夹的完整相对路径是 ./prod-secret/.git,它也不匹配 glob 模式。因此,这两个文件夹都不会添加到存档中。

9. 格式化进度输出信息

默认情况下,zip命令通过标准输出报告操作的进度。我们可以使用多种选项来自定义此输出。

9.1. 抑制进度输出

使用标志 -q,我们可以防止 zip命令显示任何输出消息

$ zip -q -r all.zip .

正如我们所见,当标志*-q*存在时, zip命令不会输出任何进度消息 。

9.2. 以字节显示进度

要根据要归档的字节数显示进度输出,我们可以传递标志-db**:

$ zip -r -db all.zip .
[   0/  91]   adding: prod-secret/ (stored 0%)
[   0/  91]   adding: prod-secret/mysql-passwd.secret (stored 0%)
[  13/  78]   adding: prod-secret/mongo-passwd.secret (stored 0%)
[  26/  65]   adding: prod-secret/kafka-passwd.secret (stored 0%)
[  39/  52]   adding: prod-secret/.git/ (stored 0%)
[  39/  52]   adding: prod-secret/.git/branch (stored 0%)
[  46/  45]   adding: prod-secret/.git/HEAD (stored 0%)
[  51/  40]   adding: customer-details.txt (stored 0%)
[  67/  24]   adding: credentials.txt (stored 0%)
[  75/  16]   adding: .git/ (stored 0%)
[  75/  16]   adding: .git/tag (stored 0%)
[  79/  12]   adding: .git/branch (stored 0%)
[  86/   5]   adding: .git/HEAD (stored 0%)

使用标志 -db时,zip命令在进度输出之前使用包含两个数字的方括号。左边的数字表示已归档的字节数,而右边的数字表示剩余要归档的字节数。

9.3. 显示计数进度

或者,我们可以使用选项标志*-dc*显示文件和目录计数方面的进度

$ zip -r -dc all.zip .
  0/ 13 updating: prod-secret/ (stored 0%)
  1/ 12 updating: prod-secret/mysql-passwd.secret (stored 0%)
  2/ 11 updating: prod-secret/mongo-passwd.secret (stored 0%)
  3/ 10 updating: prod-secret/kafka-passwd.secret (stored 0%)
  4/  9 updating: prod-secret/.git/ (stored 0%)
  5/  8 updating: prod-secret/.git/branch (stored 0%)
  6/  7 updating: prod-secret/.git/HEAD (stored 0%)
  7/  6 updating: customer-details.txt (stored 0%)
  8/  5 updating: credentials.txt (stored 0%)
  9/  4 updating: .git/ (stored 0%)
 10/  3 updating: .git/tag (stored 0%)
 11/  2 updating: .git/branch (stored 0%)
 12/  1 updating: .git/HEAD (stored 0%)

左边的数字显示到目前为止已存档的文件数,而右边的数字显示等待存档的文件数。

10. 将文件和文件夹移动到存档中

使用选项-m,  zip命令会将文件和目录移动到存档中**。换句话说,已经归档的文件和文件夹将被删除

让我们在我们的目录上运行 带有选项 -mzip命令:

$ ls
credentials.txt   customer-details.txt  prod-secret
$ zip -m backup.zip credentials.txt
  adding: credentials.txt (stored 0%)
$ ls
backup.zip  customer-details.txt  prod-secret

如我们所见,将文件 credentials.txt移动到存档 backup.zip后,文件 credentials.txt被删除。

11. 刷新档案

zip命令还通过标志-f支持刷新模式。**在此模式下,zip命令不会将新文件添加到存档中。相反,它只会更新存档中的文件。

例如,当前目录包含一个存档 credentials-archive.zip和一些其他文件:

$ ls -l
total 16
-rw-r--r-- 1 david david    17 May  3 21:22 credentials.txt
-rw-r--r-- 1 david david   197 May  3 21:23 credentials-archive.zip
-rw-r--r-- 1 david david    16 May  3 16:17 customer-details.txt
drwxr-xr-x 3 david david  4096 May  3 16:17 prod-secret

此外,存档 credentials-archive.zip仅包含文件 credentials.txt

$ zipinfo credentials-archive.zip
Archive:  credentials-archive.zip
Zip file size: 197 bytes, number of entries: 1
-rw-r--r--  3.0 unx       17 tx stor 21-May-03 21:22 credentials.txt
1 file, 17 bytes uncompressed, 17 bytes compressed:  0.0%

现在,让我们 通过向其中添加新行来修改credentials.txt文件:

$ echo "id=1234;password=4321" >> credentials.txt
$ ls -l credentials.txt
-rw-r--r-- 1 root root 39 May  3 21:27 credentials.txt

请注意,文件credentials.txt的时间戳和大小 都已更新。

现在,我们可以在刷新模式下运行 zip命令来更新存档中的credentials.txt文件:

$ zip -r -f credentials-archive.zip .
freshening: credentials.txt (deflated 5%)

虽然我们在命令中指定了标志 -r,但它不会将其他新文件引入存档。这是因为使用刷新模式时,zip命令不会将新文件添加到存档中。如果我们没有在刷新模式下运行该命令,则zip命令会在存档中包含当前目录中的所有内容。

让我们看看更新后的 credentials-archive.zip存档:

$ zipinfo credentials-archive.zip
Archive:  credentials-archive.zip
Zip file size: 217 bytes, number of entries: 1
-rw-r--r--  3.0 unx       39 tx defN 21-May-03 21:27 credentials.txt
1 file, 39 bytes uncompressed, 37 bytes compressed:  5.1%

正如我们所观察到的,  zip命令将存档中的文件更新为最新版本。此外,它不包括同一目录中的其余文件。