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

新手上路,请多包涵

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

原文由 subcan 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 755
2 个回答

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

有一个系统调用用于重命名在 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 的调用将失败,因为它们需要按名称引用文件。

原文由 Robert Martin 发布,翻译遵循 CC BY-SA 3.0 许可协议

您可以使用显示为 / 的 Unicode 字符(例如 分数斜杠),假设您的文件系统支持它。

原文由 Blackle Mori 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题