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

19 linux filenames command-line

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

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

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

Jör*_*tag 67

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

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

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

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

ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
0123456789._-
您可以依赖的最大文件名长度在第13.23.3.5节(<limits.h>最小值)中定义为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上,那么您必须在任何地方禁用连字符,而不仅仅是第一个字符.现在,剩下的字符集看起来像

ABCDEFGHIJKLMNOPQRSTUVWXYZ
0123456789_
它为您提供3512479453921组合(41位).

  • @ acidzombie24:*压倒性的*大多数CD格式化为ISO9660 Level 2,**允许连字符和更长的文件名.连字符只在ISO9660 1级上是非法的,几乎没有人使用.我只是提到完整性.另请注意,我没有对MacOS说什么,只是因为我对它不了解.再一次,Apple实际上已经解决了OSX中几乎所有古老的MacOS限制,所以它可能不太相关. (3认同)
  • BTW POSIX*允许*UTF-8 Unicode; 它只强制要求符合POSIX标准的*最小*字符集.大多数POSIX文件系统允许任何不包含'/'或'\ 0'的字节序列,但便携式应用程序不应该依赖于此. (3认同)
  • 各种操作系统也不允许某些序列,即使它们遵守规则也是如此.例如,Windows上不允许使用"CON". (2认同)

Gre*_*ill 6

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

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


Jer*_*fin 5

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