答案是你不能,除非你的文件系统有错误。原因如下: 有一个系统调用用于重命名在 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 许可协议
答案是你不能,除非你的文件系统有错误。原因如下:
有一个系统调用用于重命名在
fs/namei.c
中定义的文件,称为renameat
:当系统调用被调用时,它会对名称进行路径查找(
do_path_lookup
)。继续跟踪这个,我们得到link_path_walk
它有这个:此代码适用于任何文件系统。这是什么意思?这意味着,如果您尝试使用传统方式传递带有实际
'/'
字符作为文件名的参数,它将无法执行您想要的操作。没有办法逃脱角色。如果文件系统“支持”这一点,那是因为它们要么:此外,如果您 确实 进入并编辑字节以将斜杠字符添加到文件名中,则会发生不好的事情。那是因为您永远无法通过名称引用此文件:( 因为无论何时,Linux 都会假定您引用的是一个不存在的目录。使用 ‘rm *’ 技术也不起作用,因为 bash 只是将其扩展为文件名。甚至
rm -rf
也不起作用,因为一个简单的 strace 揭示了事情在幕后是如何发生的(缩短):请注意,这些对
unlinkat
的调用将失败,因为它们需要按名称引用文件。