Linux 是否可以在文件名中使用“/”?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9847288/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is it possible to use "/" in a filename?
提问by subcan
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?
我知道这不是应该做的事情,但是有没有办法在 Linux 中使用通常在文件名中分隔目录的斜杠字符?
采纳答案by Robert Martin
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
:
有一个系统调用用于重命名在fs/namei.c
调用中定义的文件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:
当系统调用被调用时,它会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;
...
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 lookslike a slash but isn't.
- They have a bug.
- 使用 unicode 字符或看起来像斜杠但不是斜杠的东西。
- 他们有一个错误。
Furthermore, if you didgo 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):
此外,如果您确实进入并编辑字节以在文件名中添加斜杠字符,则会发生不好的事情。那是因为您永远无法按名称引用此文件 :( 因为无论何时您这样做,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
...
Notice that these calls to unlinkat
would fail because they need to refer to the files by name.
请注意,这些调用unlinkat
将失败,因为它们需要按名称引用文件。
回答by Blackle Mori
You could use a Unicode character that displays as "/" (for example this seemingly redundant glyph) assuming your filesystem supports it.
假设您的文件系统支持它,您可以使用显示为“/”的 Unicode 字符(例如这个看似多余的字形)。
回答by keyser
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.
并且,如前所述,您可以显示一个“看起来像”斜杠的 unicode 字符,但这就是您所能得到的。
回答by David Schwartz
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.
仅使用商定的编码。例如,您可以同意%
将被编码为%%
并且这%2F
将意味着/
. 所有访问此文件的软件都必须了解编码。
回答by Nicolas
回答by Joe McMahon
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.
您是否考虑过对 URL 进行 URL 编码,然后将其用作文件名?结果作为文件名应该没问题,并且很容易从编码版本重建名称。
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.
另一种选择是创建一个索引 - 使用您喜欢的任何方法创建输出文件名 - 顺序编号的名称、SHA1 哈希等 - 然后使用生成的文件名/URL 对写入文件。您可以将它保存到一个散列中,并使用它来执行 URL 到文件名的查找,反之亦然,反之亦然,您可以将其写出并在需要时稍后重新加载。