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

时间:2010-02-20 23:46:07

标签: linux command-line filenames

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

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

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

6 个答案:

答案 0 :(得分:67)

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

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

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

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

ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
0123456789._-
您可以依赖的最大文件名长度在Section 13.23.3.5 (<limits.h> Minimum Values)中定义为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)。 / p>

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

ABCDEFGHIJKLMNOPQRSTUVWXYZ
0123456789_
,它为您提供了3512479453921个组合(41位)。

答案 1 :(得分:6)

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

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

答案 2 :(得分:5)

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

答案 3 :(得分:3)

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

答案 4 :(得分:0)

urlencode将所有字符串用作文件名,您只需要担心长度。 This answer可能值得一读。

答案 5 :(得分:0)

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

一定要允许人们使用a-z 0-9和unicode字符&gt; 0x80,但不允许任意符号,例如&amp;并且,会引起很多烦恼,以及在不适当的地方举行全程活动。

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

在文件名中允许任何其他ascii符号会造成麻烦。

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