关于linux:我不允许在文件名中使用什么字符序列?

What character sequence should I not allow in a filename?

我在测试后发现linux允许文件名中除/和null(\0)之外的任何字符。 那么我不应该在文件名中允许什么序列? 我听说一个领先的-可能会混淆一些命令行程序,这对我来说无关紧要,但如果他们决定收集一堆文件并用一些GNU程序过滤它,它可能会打扰其他人。

建议我删除前导和尾随空格,我计划只是因为通常用户并不意味着有前导/尾随空格。

可能存在哪些有问题的序列以及我应该考虑不允许的序列?
我也在考虑为了方便而不允许在Windows中使用非法字符。 我想我可能不会在开头允许短划线(破折号是一个合法的窗口角色)


你的问题有点令人困惑,因为你详细谈论Linux,但是在对另一个答案的评论中,你说你正在为人们下载生成文件名,这可能意味着你对文件系统和操作系统完全没有任何控制权。文件将被存储,使Linux完全无关紧要。

出于这个答案的目的,我将假设你的问题是错误的,你的评论是正确的。

目前使用的绝大多数操作系统和文件系统大致分为三类:POSIX,Windows和MacOS。

POSIX规范非常清楚可以保证在所有POSIX系统中可移植的文件名是什么样的。您可以使用的字符在Open Group Base Specification的第3.276节(可移植文件名字符集)中定义为:

1
2
3
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
0123456789._-

您可以依赖的最大文件名长度在第13.23.3.5节中定义(最小值)as 14。 (相关常数_POSIX_NAME_MAX。)

因此,一个长达14个字符且仅包含上面列出的65个字符的文件名在所有符合POSIX标准的系统上都可以安全使用,它可以为您提供24407335764928225040435790组合(或大约84位)。

如果您不想惹恼用户,则应添加两个限制:不要使用短划线或点开始文件名。以点开头的文件名通常被解释为"隐藏"文件,除非明确请求,否则不会显示在目录列表中。并且以破折号开头的文件名可以被许多命令解释为选项。 (旁注:很多用户不知道rm ./-rfrm -- -rf技巧,真是太棒了。)

这使您处于23656340818315048885345458组合(仍为84位)。

Windows为此添加了一些新的限制:文件名不能以点结尾,文件名不区分大小写。这会将字符集从65个字符减少到39个字符(第一个字符为37个,最后一个字符为38个字符)。它没有添加任何长度限制,Windows可以处理14个字符就好了。

这将可能的组合减少到17866587696996781449603(73位)。

另一个限制是Windows将最后一个点之后的所有内容视为文件扩展名,表示文件的类型。如果你想避免潜在的混淆(比如,如果为文本文件生成像abc.mp3这样的文件名),你应该完全避免使用点。

您仍然有13090925539866773438463组合(73位)。

如果您不得不担心DOS,则适用其他限制:文件名由一个或两个部分组成(用点分隔),其中两个部分都不能包含点。第一部分的最大长度为8,3个字符中的第二个。同样,第二部分通常保留用于指示文件类型,只留下8个字符。

现在您有4347792138495个可能的文件名或41位。

好消息是您可以使用3个字符的扩展名来实际正确地指示文件类型,而不会破坏POSIX文件名限制(8 + 3 + 1 = 12 <14)。

如果您希望用户能够将文件刻录到使用ISO9660 Level 1格式化的CD-R上,那么您必须在任何地方禁用连字符,而不仅仅是第一个字符。现在,剩下的字符集看起来像

1
2
ABCDEFGHIJKLMNOPQRSTUVWXYZ
0123456789_

,它为您提供3512479453921组合(41位)。


我会决定什么是"有效"的操作系统和文件系统驱动程序。让用户输入他们想要的任何内容,然后传递给他们。以适当的方式处理来自操作系统的错误。例外情况是我认为剥离前导和尾随空格是合理的。如果人们想要创建带有嵌入空格或前导破折号或问号的文件名,并且他们选择的文件系统允许它,那么您应该尝试阻止它们。

可以在不同的安装点(或Windows中的驱动器)上安装不同的文件系统,这些文件系统对文件名中的合法字符有不同的规则。在你的应用程序中处理这类事情将比必要的工作更多,因为操作系统已经为你做了。


由于您似乎主要对Linux感兴趣,因此要避免的一件事是(典型的)shell将尝试解释的字符,例如,作为通配符。如果你坚持,你可以创建一个名为"*"的文件,但是你可能会有一些用户不喜欢它。


您是否正在开发一个应用程序,您必须要求用户自己创建文件?如果这就是您正在做的事情,那么您可以在应用程序中设置规则。 (例如,只允许[a-zA-Z0-9_。]并拒绝其余的特殊字符。)执行起来要简单得多。


我建议使用一组白名单字符。通常,文件名中的符号会使人烦恼。

通过各种方式允许人们使用a-z 0-9和unicode字符> 0x80,但不允许任意符号,例如&amp;而且,会造成很多烦恼,以及在不适当的地方举行。

我认为可以安全使用的ASCII符号是:fullstop下划线连字符

允许文件名中的任何其他ascii符号都会出现问题。

文件名也不应以ascii符号开头。文件名中的空格策略是棘手的,因为用户可能希望能够使用它们,但是一些文件名显然是愚蠢的(例如那些以空格开头的文件名)


urlencode所有字符串都用作文件名,你只需要担心长度。这个答案可能值得一读。