是否可以在文件名中使用"/"?

sub*_*can 98 unix linux directory filenames slash

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

Rob*_*tin 122

答案是你不能,除非你的文件系统有bug.原因如下:

有一个系统调用在重命名定义文件fs/namei.c名为renameat:

SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname,
                int, newdfd, const char __user *, newname)
Run Code Online (Sandbox Code Playgroud)

调用系统调用时,它会对名称执行路径查找(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;
...
Run Code Online (Sandbox Code Playgroud)

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

  • 使用Unicode字符或东西看起来像一个斜杠,但不是.
  • 他们有一个bug.

此外,如果您确实进入并编辑了字节以将斜杠字符添加到文件名中,则会发生错误.那是因为你永远不能通过名字引用这个文件:(因为你做的任何时候,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
...
Run Code Online (Sandbox Code Playgroud)

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

  • 另请注意,至少`e2fsck`认为任何文件名都是必须修复的非法文件名 - [参见来源](http://git.kernel.org/?p=fs/ext2/e2fsprogs.git ;a =斑点; F =的e2fsck/pass2.c#l455).因此,如果你以某种方式最终得到一个带有斜杠的文件名,你可以使用`fsck`来解决问题. (7认同)
  • @ehabkost *任何*文件名?听起来像是e2fsck中的错误:p (2认同)

Bla*_*ori 32

假设您的文件系统支持它,您可以使用显示为"/"的Unicode字符(例如,这个看似冗余的字形).

  • 是的,确切地说:只有/,这是U + 002F`SOLIDUS`,是被禁止的.还有很多其他合适的候选人:/是U + 2044`FRACTION SLASH`; /是U + 2215`DIVISION SLASH`; ⧸是U + 29F8`BIG SOLIDUS`; /是U + FF0F`FULLWIDTH SOLIDUS`,╱是U + 2571是`BOX DRAW LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT`.一切都会令人钦佩! (36认同)
  • 但是,如果用户在文件名/目录名中使用这些实际字符怎么办?我们需要一个通用的转义解决方案。太糟糕了,Linux的常规代码不支持任何常规代码,因为它在ASCII 0x2F上确实匹配。至少从20年以来,ASCII就一直存在。(Unicode 1.0始于1991年!) (2认同)

Nic*_*las 8

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

  • @tchrist对不起."正斜杠"是完全[可接受的](http://en.wikipedia.org/wiki/Slash_(标点符号))引用斜杠字符的方式,以彻底清楚哪些[斜杠](http:// en. wikipedia.org/wiki/Slash_(musician))一指.有时人们会感到困惑:P (19认同)
  • 正斜杠字符被硬编码到内核中,独立于文件系统(尝试在内核源代码中执行 `grep -r "'/'" *`) (3认同)
  • 它不仅仅依赖于文件系统,所有 *nix 系统中的系统调用都会将 / 解析为目录树的一个组件。 (2认同)
  • 哈,但是我想@tchrist也有一点。为什么正向”表示“ /”而“反向”表示“ \”?到目前为止,我最好的解释是,如果用钢笔从下往上书写,则读/写时,“ /”会向右或向前移动,“ \”会向左或向后移动从左到右。不过,我不太喜欢这种解释,部分原因是我并不总是从下往上写我的角色并向上移动。我认为从顶部开始向下移动同时写一个字符通常会更好。 (2认同)
  • @jwso这完全是一个补充,但这是标准的规范语言。斜杠不是Unicode看起来像这些符号的符号,而是称其为固线,但是“ \”是反向固线,它与向后(反斜线)同义。但是,如果需要对齐,则后退和前进是线条倾斜或应该掉落的方向,其方向基于书写方向(从左到右)。如果它看起来像“ \”,则倾斜或应该下降<==或向后倾斜;如果它看起来像“ /”,则倾斜==>或向前倾斜。 (2认同)

Dav*_*rtz 6

仅使用商定的编码。例如,您可以同意%将被编码为%%并且这%2F将意味着/. 所有访问此文件的软件都必须了解编码。

  • “我们称之为斜线的任何其他名称都会闻起来很臭”——莎士比亚 (20认同)