在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. 列出档案内容而不解档
有时,我们可能只想看一眼档案的内容而不解压它。这可以使用zipinfo 和unzip 命令轻松实现,这两个命令都随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 -d从important-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:
但是,我们仍然可以在不知道密码的情况下使用zipinfo和unzip 等工具列出加密存档的内容:
$ 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命令不会递归地归档目录。通过使用标志-r,zip将递归地遍历子目录并归档它们的文件**。 例如,假设我们有一个包含一些秘密文件的目录prod-secret :
$ ls prod-secret
kafka-passwd.secret mongo-passwd.secret mysql-passwd.secret
要创建整个prod-secret目录的存档,我们可以运行带有标志 -r的zip命令:
$ 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命令会将文件和目录移动到存档中**。换句话说,已经归档的文件和文件夹将被删除。
让我们在我们的目录上运行 带有选项 -m 的zip命令:
$ 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命令将存档中的文件更新为最新版本。此外,它不包括同一目录中的其余文件。