可以使用“/”在文件名? [英] Is it possible to use "/" in a filename?

查看:230
本文介绍了可以使用“/”在文件名?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

解决方案

答案是你不能,除非你的文件系统有一个错误。这就是为什么:



有一个系统调用重命名您在 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(标志FD_CLOEXEC)
close(3)= 0
unlinkat(AT_FDCWD,testdir,AT_REMOVEDIR)= 0
...

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


I know that this is not something that should ever be done, but is there a way to use the slash character that normally separates directories within a filename in Linux?

解决方案

The answer is that you can't, unless your filesystem has a bug. Here's why:

There is a system call for renaming your file defined in fs/namei.c called renameat:

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

When the system call gets invoked, it does a path lookup (do_path_lookup) on the name. Keep tracing this, and we get to link_path_walk which has this:

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;
...

This code applies to any file system. What's this mean? It means that if you try to pass a parameter with an actual '/' character as the name of the file using traditional means, it will not do what you want. There is no way to escape the character. If a filesystem "supports" this, it's because they either:

  • Use a unicode character or something that looks like a slash but isn't.
  • They have a bug.

Furthermore, if you did go in and edit the bytes to add a slash character into a file name, bad things would happen. That's because you could never refer to this file by name :( since anytime you did, Linux would assume you were referring to a nonexistent directory. Using the 'rm *' technique would not work either, since bash simply expands that to the filename. Even rm -rf wouldn't work, since a simple strace reveals how things go on under the hood (shortened):

$ 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
...

Notice that these calls to unlinkat would fail because they need to refer to the files by name.

这篇关于可以使用“/”在文件名?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆