可以在文件名中使用“ /”吗?


111

我知道这不是应该做的事情,但是有没有办法使用斜线字符来分隔Linux中文件名中的目录?


1
我猜您可以通过直接访问您的hardisk分区并在某处的“ /”字符中打补丁来修改文件名。发生的是一个有趣的问题……很可能不是您想要的。
hochl 2012年

1
但是简短的答案应该是:不,这不是应该做的事情:-)
Simeon Visser 2012年

在FS的目录条目中的文件名中加入斜杠是否计数?不推荐使用;您将永远无法访问该文件。
乔纳森·勒夫勒

35
这让我想起了我的朋友创建一个名为的文件*然后问:“如何删除文件?”的时间。我回答了,rm然后是文件名。好吧,你知道其余的。
David Heffernan

1
对于新的Linux用户,当您对表达式或文件名不确定时,我认为这是一个好习惯,它ls用于列出要删除的文件,然后将ls命令更改为rm之后的命令。
戴夫F,

Answers:


129

答案是,除非文件系统有错误,否则您将无法这样做。原因如下:

有一个系统调用,用于重命名fs/namei.c名为的文件renameat

SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname,
                int, newdfd, const char __user *, newname)

当系统调用被调用时,它将do_path_lookup对名称进行路径查找()。继续跟踪,我们将获得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;
...

此代码适用于任何文件系统。什么意思 这意味着,如果您尝试'/'使用传统方式将带有实际字符的参数作为文件名传递,它将无法执行您想要的操作。无法逃脱角色。如果文件系统“支持”此文件,则是因为它们:

  • 使用unicode字符或看起来像斜杠但不是的字符。
  • 他们有一个错误。

此外,如果确实要编辑字节以在文件名中添加斜杠字符,则可能会发生不良情况。那是因为您永远无法使用名称:(来引用该文件,因为无论何时,Linux都会假定您所引用的目录不存在。使用'rm *'技术也不起作用,因为bash只是将其扩展为文件名。甚至rm -rf都行不通,因为简单的strace可以揭示幕后情况(简称):

$ ls testdir
myfile2 out
$ strace -vf rm -rf testdir
...
unlinkat(3, "myfile2", 0)               = 0
unlinkat(3, "out", 0)                   = 0
fcntl(3, F_GETFD)                       = 0x1 (flags FD_CLOEXEC)
close(3)                                = 0
unlinkat(AT_FDCWD, "testdir", AT_REMOVEDIR) = 0
...

注意,对这些的调用unlinkat将失败,因为它们需要按名称引用文件。


8
另外,请注意,至少e2fsck将任何文件名视为必须修复的非法文件名(请参阅source)。因此,如果您以某种方式以带有斜杠的文件名结尾,则可以使用它fsck来解决问题。
ehabkost 2012年

4
@ehabkost 任何文件名?听起来像是一个虫子e2fsck:p
flarn2006 '18

36

假设文件系统支持,则可以使用显示为“ /”的Unicode字符(例如,这个看似多余的字形)。


43
是的,正好:仅/是U + 002F SOLIDUS,被禁止。还有许多其他合适的候选者:⁄是U + 2044 FRACTION SLASH;∕是U + 2215 DIVISION SLASH; ⧸是U + 29F8 BIG SOLIDUS; /是U + FF0F FULLWIDTH SOLIDUS,╱是U + 2571是BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT。一切都会令人钦佩!
tchrist 2012年

2
但是,如果用户在文件名/目录名中使用这些实际字符怎么办?我们需要一个通用的转义解决方案。太糟糕了,Linux的常规代码不支持任何常规代码,因为它在ASCII 0x2F上确实匹配。至少从20年以来,ASCII就一直存在。(Unicode 1.0从1991年开始!)
Evi1M4chine

@tchrist我不想依赖unicode。所以我可能更喜欢像这样的多字符定界符---。您选择的分度符可以使用其他字符,并可以改变重复次数。
Trevor Boyd Smith,

有关在不同文件系统下禁止的许多字符上可能替换的列表,请查看我的答案:stackoverflow.com/a/61448658/4575793
Cadoiz

9

这取决于您使用的文件系统。在一些比较流行的:


1
它不仅仅取决于文件系统,所有* nix系统中的系统调用都会将/解析为目录树的组成部分。
Blackle Mori 2012年

2
独立于文件系统,正斜杠字符被硬编码到内核中(尝试grep -r "'/'" *在您的内核源代码中进行)
Robert Martin

20
@tchrist对不起。“正斜杠”是一种完全可接受的方式,用于指代斜杠字符以完全弄清楚一个斜杠是指哪个斜杠。有时人们会感到困惑:P
罗伯特·马丁

2
哈,但我想@tchrist也有一点。为什么正向”表示“ /”而“反向”表示“ \”?到目前为止,我最好的解释是,如果用钢笔从一行开始,从下往上书写,则读/写时,“ /”向右或“向前”移动,“ \”向左或“向后”移动从左到右。不过,我不太喜欢这种解释,部分原因是我并不总是从下往上写我的角色。我认为从上而下往下移动通常会更好。
杰西·科林斯

4
@jwso这完全是一个补充,但这是标准的规范语言。斜杠不是Unicode看起来像这些符号的符号,而是称其为固线,但是“ \”是反向固线,它与向后(反斜线)同义。但是,如果需要对齐,则后退和前进是线条倾斜或应该掉落的方向,其方向基于书写方向(从左到右)。如果它看起来像“ \”,则倾斜或应该下降<==或向后倾斜;如果它看起来像“ /”,则倾斜==>或向前倾斜。
Stuart R. Jefferys

4

仅使用约定的编码。例如,你可以同意,%将被编码为%%%2F将意味着一个/。访问此文件的所有软件都必须了解编码。


19
“我们称其为斜线的任何东西都会闻起来很臭” –莎士比亚
罗伯特·马丁

1

简短的答案是:不,您不能。由于目录结构是如何定义的,因此这是必要的禁止。

而且,如前所述,您可以显示一个“看起来像”斜杠的unicode字符,但这已尽其所能。


1

通常,在文件名中完全使用“坏”字符是个坏主意。即使您以某种方式进行管理,它也会使以后很难使用该文件。文件系统分隔符完全无法使用,因此您需要选择一种替代方法。

您是否考虑过对URL进行URL编码然后使用URL作为文件名?结果应该是文件名,并且可以很容易地从编码版本中重建名称。

另一种选择是创建索引-使用您喜欢的任何方法创建输出文件名-顺序编号的名称,SHA1哈希等-然后使用生成的文件名/ URL对写入文件。您可以将其保存到哈希中,并使用它对反向版本的哈希进行URL到文件名的查找,反之亦然,您可以将其写出并在以后需要时重新加载。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.