是否可以使用“/"?在文件名中? [英] Is it possible to use "/" in a filename?
问题描述
我知道这不是应该做的事情,但是有没有办法在 Linux 中使用通常在文件名中分隔目录的斜杠字符?
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:
有一个用于重命名在 fs/namei.c
中定义的文件的系统调用,称为 renameat
:
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)
当系统调用被调用时,它会在名称上进行路径查找 (do_path_lookup
).继续跟踪这个,我们得到 link_path_walk
有这个:
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:
- 使用 unicode 字符或看起来像斜杠但不是斜杠的东西.
- 他们有一个错误.
- Use a unicode character or something that looks like a slash but isn't.
- They have a bug.
此外,如果您确实进入并编辑字节以在文件名中添加斜杠字符,则会发生不好的事情.那是因为您永远无法按名称引用此文件 :( 因为无论何时您这样做,Linux 都会假定您引用的是一个不存在的目录.使用 'rm *' 技术也不起作用,因为 bash 只是将其扩展为文件名.甚至 rm -rf
也行不通,因为一个简单的 strace 揭示了引擎盖下的事情(缩短):
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
...
请注意,这些对 unlinkat
的调用将失败,因为它们需要按名称引用文件.
Notice that these calls to unlinkat
would fail because they need to refer to the files by name.
这篇关于是否可以使用“/"?在文件名中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!