Is it possible to use “/” in a filename?

不羁的心 提交于 2019-11-26 01:42:59

问题


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?


回答1:


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.




回答2:


You could use a Unicode character that displays as "/" (for example this seemingly redundant glyph) assuming your filesystem supports it.




回答3:


It depends on what filesystem you are using. Of some of the more popular ones:

  • ext3: No
  • ext4: No
  • jfs: Yes
  • reiserfs: No
  • xfs: No



回答4:


Only with an agreed-upon encoding. For example, you could agree that % will be encoded as %% and that %2F will mean a /. All the software that accessed this file would have to understand the encoding.




回答5:


The short answer is: No, you can't. It's a necessary prohibition because of how the directory structure is defined.

And, as mentioned, you can display a unicode character that "looks like" a slash, but that's as far as you get.




回答6:


In general it's a bad idea to try to use "bad" characters in a file name at all; even if you somehow manage it, it tends to make it hard to use the file later. The filesystem separator is flat-out not going to work at all, so you're going to need to pick an alternative method.

Have you considered URL-encoding the URL then using that as the filename? The result should be fine as a filename, and it's easy to reconstruct the name from the encoded version.

Another option is to create an index - create the output filename using whatever method you like - sequentially-numbered names, SHA1 hashes, whatever - then write a file with the generated filename/URL pair. You can save that into a hash and use it to do a URL-to-filename lookup or vice-versa with the reversed version of the hash, and you can write it out and reload it later if needed.



来源:https://stackoverflow.com/questions/9847288/is-it-possible-to-use-in-a-filename

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!