RAR 在压缩包中使用相对路径 (Linux版)

缘起:我需要备份博客源文件

我想把我的博客(以下简称 本博 )的源文件打包压缩备份到本地。

所以,我在 Linux (此处以 Kali Linux 为例)下安装了 rar。

1
sudo apt-get install rar

rar 将博客源文件所在的目录 ~/kukmoon_blog 打包[1]

1
rar u -r /tmp/kukmoon_blog.rar ~/kukmoon_blog

但是,我发现,rar 把绝对路径也放进了压缩包。这个压缩包打开以后,上来第一层是 home 目录,第二层是 Kukmoon 目录,第三层是 kukmoon_blog 目录,到第四层才是所有的博客源文件。

我懒得录屏了,用 Windows 版的代替吧

**怎样才能让 rar.exe 在压缩包里使用相对路径呢?**我的要求是,打开压缩包,第一层就是 kukmoon_blog 目录。

我懒得录屏了,用 Windows 版的代替吧

rar 的 -ep1 开关

经过摸索,我在 rar 控制台版本的用户手册[2]里找到了一个 -ep1 开关。这个开关可以在压缩包内去掉上一层目录,相当于使用相对路径,可搭配 rar 的 au 命令使用。

官方对这个开关的解释是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
-ep1    Exclude base dir from names. Do not store the path entered
in the command line.

Example:

all files and directories from the directory tmp will be added
to the archive 'test', but the path in archived names will not
include 'tmp\'

rar a -ep1 -r test tmp\*

This is equivalent to the commands:

cd tmp
rar a -r ..\test
cd ..

例题精讲

下面我们用四道例题来解释 -ep1 参数的用法。

假设:在 ~/abc/def 目录下有个 1.txt 文件,有个 ghi 子目录,在这个子目录下有 2.txt 文件。

1
2
3
4
5
6
~/abc
~/abc/def
~/abc/def/ghi
~/abc/def/ghi/2.txt
~/abc/def/1.txt

【例 1】

执行命令:

1
rar a -r example1.rar ~/abc/def

生成的 example1.rar 的内部结构是:

1
2
3
4
5
6
7
8
9
example1.rar
└─home
└─home/kukmoon
└─home/kukmoon/abc
└─home/kukmoon/abc/def
└─home/kukmoon/abc/def/ghi
└─home/kukmoon/abc/def/ghi/2.txt
└─home/kukmoon/abc/def/1.txt

显然,如果不使用 -ep1参数,并且压缩文件里包含了每个文件和目录的全部路径,从根目录开始算。

【例 2】

执行命令:

1
rar a -r example2.rar ~/abc/def/

生成的 example2.rar 的内部结构是:

1
2
3
4
5
6
7
8
9
example2.rar
└─home
└─home/kukmoon
└─home/kukmoon/abc
└─home/kukmoon/abc/def
└─home/kukmoon/abc/def/ghi
└─home/kukmoon/abc/def/ghi/2.txt
└─home/kukmoon/abc/def/1.txt

例 2 和例 1 的区别在于,例 2 在输入列表文件(即待压缩的文件)的路径时,在 def 后面多加了一个反斜杠。加这个反斜杠的目的的指明 def 不是文件,而是子目录。

但是,生成的 example1.rarexamle2.rar 没有区别。

这说明,如果不加 -ep1 开关,那么在子目录的名称后面加不加斜杠,没有区别。

【例 3】

执行命令:

1
rar a -r -ep1 example3.rar ~/abc/def

生成的 example3.rar 的内部结构是:

1
2
3
4
5
6
example3.rar
└─def
└─def/ghi
└─def/ghi/2.txt
└─def/1.txt

例 3 和例 1 的区别在于,例 3 加入了 -ep1 开关。结果就是,abc 目录从压缩包里消失了,压缩包第一层文件结构是原来的 abc 目录里的 def 子目录。

为什么呢?

官方对这个 -ep1 参数的解释有一句话:

Exclude base dir from names.

其中,base dir 是上一层目录,例如,~/abc/def/1.txt 的 base dir 是 ``~/abc/def/` 目录。

所以,例 3 这条命令 rar a -r -ep1 example3.rar ~/abc/def 的作用是,从压缩包里排除 ~/abc 这个路径,压缩包的第一层结构是 def 子目录。

注意:如果在 ~/abc 目录中还有其它文件或子目录,rar 也会一起把它们排除,只保留 def 子目录。

【例 4】

执行命令:

1
rar a -r -ep1 example4.rar ~/abc/def/

生成的 example4.rar 的内部结构是:

1
2
3
4
5
example4.rar
└─ghi
└─ghi/2.txt
└─1.txt

例 4 和 例 3 的区别是,例 4 在输入列表文件(即待压缩的文件)的路径时,在 def 后面多加了一个反斜杠。加这个反斜杠的目的的指明 def 不是文件,而是子目录。

结果是,exampl4.rar 不但排除了 abc 目录,连 def 目录也排除了。上来第一层目录结构是原来 def 目录中的 1.txtghi 子目录。

这是为什么呢?

计算机基础知识告诉我们,目录也是个特殊的文件,需要在目录名后面加个斜杠(Unix-like 操作系统要求用正斜杠,DOS/Windows 要求用反斜杠)作为标记。

如果不加斜杠,大多数情况下,系统会自动区分,但是个别情况下,区分无效,用户需要强行用斜杠表示区分。

这就属于那种需要用户自己加斜杠来区分的类型:

  • 如果不加斜杠,比如 ~/abc/def,系统把 def 当作文件名而不是目录名,所以,base dir 是 ~/abc/ 目录。
  • 如果加了斜杠,比如 ~/abc/def/,系统把 def/ 当作目录名,那么 base dir 就是 ~/abc/def/ 目录。

我甚至怀疑,rar.exe 的源代码是这么写的:从右向左寻找第一个斜杠,把第一个斜杠左边的字符串作为 base dir,从而把它对应的目录路径从压缩包里排除出去。

【例 5】

执行命令:

1
rar a -r -ep1 example5.rar ~/abc/def/*

生成的 example5.rar 的内部结构,与 example4.rar 一样:

1
2
3
4
5
example5.rar
└─ghi
└─ghi/2.txt
└─1.txt

注意事项

  1. 无论是不是加 -ep1 开关,rar 都会把 ~~/abc 目录中的其它内容(包括文件、子目录、子目录中的文件)排除掉,只保留 ~/abc/def/ 目录下的内容。

  2. 7z 默认排除 base dir,不用问 7z 用什么开关才能排除 base dir。

图片版权

头图:Banner Image by milkusmaximus from Pixabay

参考文献


求扫码打赏
“我这么可爱,请给我钱 o(*^ω^*)o”

RAR 在压缩包中使用相对路径 (Linux版)
https://blog.kukmoon.com/8350120a/
作者
Kukmoon谷月
发布于
2022年3月18日
许可协议