我知道这不是应该做的事情,但是有没有办法使用通常在 Linux 中分隔文件名中的目录的斜线字符?
8 回答
答案是你不能,除非你的文件系统有错误。原因如下:
有一个系统调用用于重命名中定义的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 只是将它扩展为文件名。 Evenrm -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
将失败,因为它们需要按名称引用文件。
假设您的文件系统支持它,您可以使用显示为“/”的 Unicode 字符(例如这个看似多余的字形)。
仅使用商定的编码。例如,您可以同意%
将被编码为%%
,这%2F
意味着/
. 访问此文件的所有软件都必须了解编码。
简短的回答是:不,你不能。由于目录结构的定义方式,这是必要的禁止。
而且,如前所述,您可以显示一个“看起来像”斜杠的 unicode 字符,但仅此而已。
一般来说,尝试在文件名中使用“坏”字符是个坏主意。即使您以某种方式管理它,它也往往会使以后难以使用该文件。文件系统分隔符完全不起作用,因此您需要选择一种替代方法。
您是否考虑过对 URL 进行 URL 编码然后将其用作文件名?结果应该可以作为文件名,并且很容易从编码版本中重建名称。
另一种选择是创建一个索引 - 使用您喜欢的任何方法创建输出文件名 - 顺序编号的名称、SHA1 哈希值等等 - 然后使用生成的文件名/URL 对写入一个文件。您可以将其保存到散列中并使用它进行 URL-to-filename 查找,反之亦然,使用反向版本的散列,如果需要,您可以将其写出来并在以后重新加载。
简短的回答是:你不能。长答案是,您可能可以或者这取决于您从哪里查看它以及您正在使用哪个层。
由于问题中有Unix
标签,我将回答Unix
。
正如其他答案中提到的那样,您不能在 filename 中使用正斜杠。
但是,MacOS
您可以通过以下方式创建带有正斜杠的文件/
:
# avoid doing it at all cost
touch 'foo:bar'
现在,当你从终端看到这个文件名时,你会看到它foo:bar
但是,如果您从finder
: 中看到它,您会看到 finder 将其转换为foo/bar
同样的事情可以反过来做,如果你从 finder 创建一个带有正斜杠的文件,比如/foobar
,将在后台完成转换。结果,您将:foobar
在终端中看到,但从取景器中查看时则相反。
因此,:
在 中有效unix layer
,但它/
在 Mac 层(如 Finder 窗口、GUI)中转换为或从其转换。:
冒号用作分隔符,HFS paths
斜杠/
用作分隔符POSIX paths
因此,会发生双向转换,具体取决于您正在使用的“层”。
在此处查看更多详细信息:https ://apple.stackexchange.com/a/283095/323181
在 Linux 和 Unix 中,您可以使用带有 / 的文件名。这是一个非常古老的问题,但令人惊讶的是,自从提出这个问题以来,近 10 年都没有人说过这个问题。
每个 Unix 和 Linux 系统都有名为 / 的根目录。目录只是一种特殊的文件。符号链接、字符设备等也是特殊类型的文件。请参阅此处进行深入讨论。
您不能使用 / 创建任何其他文件,但您肯定有一个 - 并且是一个非常重要的文件。