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 ./-rf或rm -- -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位).
我会决定什么是"有效"的操作系统和文件系统驱动程序.让用户输入他们想要的任何内容,然后传递给他们.以适当的方式处理来自操作系统的错误.例外情况是我认为剥离前导和尾随空格是合理的.如果人们想要创建带有嵌入空格或前导破折号或问号的文件名,并且他们选择的文件系统允许它,则不应该由您来尝试阻止它们.
可以在不同的安装点(或Windows中的驱动器)上安装不同的文件系统,这些文件系统对文件名中的合法字符有不同的规则.在你的应用程序中处理这类事情将比必要的工作更多,因为操作系统已经为你做了.
由于您似乎主要对Linux感兴趣,因此要避免的一件事是(典型的)shell将尝试解释的字符,例如,作为通配符.如果你坚持,你可以创建一个名为"*"的文件,但是你可能会有一些用户不喜欢它.