在Linux中的文件名中使用“/”
1. 概述
在本文中,我们将研究在 Linux 中将“/”字符添加到文件名的可能性。我们将介绍 Linux 内核对在文件名中使用字符的限制,然后深入研究 rename 系统调用的代码。
最后,我们将讨论一种解决方法,我们可以使用该解决方法在文件名中包含类似于“/”的 Unicode 字符。
2. 文件名中可以使用“/”吗?
Linux 限制在文件名中使用“/”(Solidus )字符,因为它保留给系统使用。 **从技术上讲,Linux 使用“/”字符作为分隔符来组织目录树。*例如,我们可以使用/dev/video0路径访问Linux 中的video0设备。在这里,我们有两个路径组件,即dev目录和video0*符号链接。在这两个名称中的任何一个中使用“/”都会影响访问目标文件位置的能力。
**因此,当文件名包含“/”字符时,Linux 内核将无法正确解析路径。因此,不可能在文件名中使用常规的“/”字符。**还有一个称为 NUL 字符 (\0) 的保留字符也被 Linux 限制不能在文件名中使用。
2.1. 重命名系统调用
renameat文件系统 调用负责定位文件并重命名它。此调用在fs/namei.c 文件中定义。每当调用此系统调用时,它都会执行路径查找。在幕后,此路径查找将调用名为link_path_walk 的函数,我们将在其中找到基本上使用“/”字符作为分隔符的检查。
让我们简单看一下这个函数:
static int link_path_walk(const char *name, struct nameidata *nd)
{
...
struct path next;
int err;
unsigned int lookup_flags = nd->flags
while (*name=='/')
name++
if (!*name)
return 0;
...
}
此函数遍历while语句中的指定文件路径。**正如我们所见,“/”分隔符在函数中是硬编码的,无法转义。因此,我们使用哪个文件系统并不重要,因为该系统调用适用于所有文件系统。**但是,如果我们确实遇到允许文件名中包含“/”字符的文件系统,则可能有两个原因:
- “/”字符不是常规的正斜杠,而是看起来像正斜杠的Unicode字符
- 文件系统包含错误
如果由于某种原因,我们仍然需要在文件名中包含“/”字符或至少一个看起来像“/”的字符,我们可以使用 Unicode 字符,我们将在下面介绍。
3. 解决方法:使用 Unicode 字符
对于 ASCII 字符集中的每个字符,该字符可能在 Unicode 集中具有相似之处。尽管不是每个系统或软件都支持 Unicode,但它仍然是主要 Linux 发行版支持的最广泛使用的标准。
3.1. Unicode 中“/”的替代方案
我们可以使用以下字符代替常规正斜杠 (U+002F):
- U+2044 = 分数斜线:⁄
- U+2215 = 除法斜线:∕
- U+29F8 = 大固体:⧸
- U+FF0F = 全宽 Solidus:╱
- U+2571 = 方框图浅对角线从右上到左下:╱
3.2. 在 Linux 的文件名中添加替代斜杠
**在 Linux 上,我们可以通过按 CTRL+SHIFT+u 键来输入 Unicode 字符。**当我们按下按键时,我们可以注意到一个带下划线的小写“u”,它表示输入 Unicode 标识符的提示。
让我们打开任何文件管理器并尝试一下:
现在,让我们输入“2215”代码并回车:
一旦我们重命名一个包含 Unicode 字符的文件,我们可以观察到我们的文件现在在文件名中包含“Division Slash”:
有时,根据字体和 Unicode 字符,该字符会与其他字符重叠。在这种情况下,我们可以尝试使用其他斜线字符来选择一个看起来更好的字符。
同样,我们也可以在大多数命令行终端上插入 Unicode 字符。但是,某些终端可能有自己的方式来添加 Unicode 字符。在这种情况下,我们可以参考他们的官方文档寻求帮助。
4. 修复包含“/”的文件名
**我们无法对文件名中包含常规“/”的文件执行正常操作。**例如,我们不能删除文件,因为它会将“/”字符视为分隔符。不仅如此,我们也不能对它执行rm *,因为 shell 会将通配符扩展为适当的文件名。
**幸运的是,我们可以通过在文件系统上运行fsck 实用程序来修复这些文件名。**大多数主要的 Linux 发行版都预装了fsck ,因此我们可以使用此实用程序从文件名中删除斜杠。在运行它之前,请确保文件系统已卸载:
# fsck -AC
-A选项在所有分区上运行fsck,而*-C*选项将显示一个进度条。