可以在文件名中使用“/”吗?

我知道这是不应该做的事情,但是有没有办法在 Linux 中使用斜杠字符来分隔文件名中的目录呢?

104363 次浏览

假设您的文件系统支持,您可以使用显示为 /(例如 分数斜线)的 Unicode字符。

简短的回答是: 不,你不能。这是一个必要的禁令,因为目录结构是如何定义的。

而且,正如前面提到的,你可以显示一个“看起来像”斜杠的 Unicode字符,但仅此而已。

只有经过商定的编码才行。例如,您可以同意 %将被编码为 %%,而 %2F将意味着 /。所有访问这个文件的软件都必须理解其编码。

这取决于您使用的是什么文件系统:

答案是,除非你的文件系统有一个 bug,否则你不能这样做:

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也不会起作用,因为一个简单的线索揭示了事情在引擎盖下是如何进行的(缩写) :

$ 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的调用将失败,因为它们需要按名称引用文件。

一般来说,尝试在文件名中使用“坏”字符是一个糟糕的主意; 即使您以某种方式管理了它,它往往会使以后很难使用该文件。文件系统分隔符完全不起作用,因此您需要选择一种替代方法。

你有没有考虑过 URL 编码的 URL,然后使用它作为文件名?结果应该可以很好地作为文件名,并且很容易从编码版本重新构建名称。

另一种选择是创建一个索引——使用任何你喜欢的方法创建输出文件名——顺序编号的名称、 SHA1散列,等等——然后用生成的文件名/URL 对写一个文件。您可以将其保存到一个散列中,并使用它来执行 URL 到文件名的查找,反之亦然,使用反向的散列版本,您可以将其写出来,并在以后需要时重新加载它。

简短的回答是: 你不能。较长的回答是,您可能可以或者它取决于您从哪里查看它,以及您在哪个层中工作。

因为这个问题有 Unix标签,所以我要回答 Unix

正如在其他答案中提到的,不能在文件名中使用正斜杠

但是,在 MacOS中,您可以通过以下方法创建带有正斜杠的 /文件:

# avoid doing it at all cost
touch 'foo:bar'

现在,当您从终端看到这个文件名时,您将看到它是 foo:bar

但是,如果你看到它从 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 系统都有名为/的根目录。目录只是一种特殊的文件。符号链接、字符设备等也是特殊类型的文件。有关详细讨论,请参阅 给你

您不能使用/创建任何其他文件,但是您肯定有一个,而且是非常重要的一个。