文件名中的空格是一个被称为“削弱”的问题。然而,似乎没有一个详细的列表来说明如何预防它们,而且常见的静态分析工具似乎也不支持预防。
在这个列表中,我想收集一些策略以防止这些错误。
在前面提到的提示也可以解决问题的情况下,明确允许提案解决问题。唯一的两个标准是
- 该策略至少在某些情况下解决了问题。
- 之前没有提到过完全相同的策略。
我的第一个贡献是:
- 调用命令行工具时,请记住引用文件名(如果允许)。特别是,当通过程序引用该工具时,不要忘记引用它。 (伪代码例如
execute "commandlinetool -r '" <> filename <> "'"
) - 一些命令行工具提供了通过在文件名中包含空格来防止错误的选项,例如
-print0
,,,xargs -0
(git-ls-files -z
来源,第 2 点) - 编程时,请注意命令行参数的类型、顺序和数量,如果这些检查失败,则快速失败。此外,在错误消息中将已识别的参数作为名称/值对进行传达。否则,带有空格的路径名可能会被“视为”多个参数,这将导致令人困惑的错误。
make
与空格一起使用相当复杂(来源)。- 使用文件名中的空格作为输入来测试程序,并在名称包含空格的目录中执行该程序及其测试套件。
答案1
文件名中的空格是一个被称为“削弱”的问题
嗯,从历史上看,你是对的,但老实说,自 ca 以来,文件名中的空格就没有出现过问题。 2001.你提出了正确的观点:
调用命令行工具时,请记住引用文件名(如果允许)。
总是允许的。
特别是,当通过程序引用该工具时,不要忘记引用它。 (伪代码例如
execute "commandlinetool -r '" <> filename <> "'"
)
当然!我会把这个指导方针放在非常高的位置。它本质上就像“如果处理整数,接受它们可能是 0 甚至负数”。因此,编写不受损坏的软件,它接受所有有效的输入。人们大多已经开始这样做,在小型私人项目之外很少看到脚本错误地执行此操作。
一些命令行工具提供了通过在文件名中包含空格来防止错误的选项
是的。这属于上面“不要编写损坏的软件”的方面:空格是文件名中的有效字符,并且从 1995 年开始在大多数操作系统上都存在。如果您的程序/脚本假定它不能出现在文件中名字,你做错了,并且你已经以某种方式在你的脑海中植入了这样的想法:这是一个有效的假设。
我认为大多数年轻的开发人员甚至不会有这样的假设!
编程时,请注意命令行参数的类型、顺序和数量,如果这些检查失败,则快速失败。
现在,这就是所谓的防御性编程。在许多情况下,这是一个好主意,在其他情况下,在某个随机点失败并向上反映该失败也是可以的。如“无法连接脑部手术机器人”;按下按钮的人没有理由想知道它失败了,因为某些配置文件中包含错误的字符,或者其他什么。
请注意,明智的错误处理实际上并不是我所知道的任何 shell 脚本语言的强项。事情比其他语言落后几十年(比如 3)(Python 有一些还过得去的异常处理,C++、Java、Rust 也是如此,或者……基本上今天的大多数语言并不像 zsh 那样糟糕,或者更糟糕,bash、ksh、切斯,...)
注意类型
您可能会注意到:shell 脚本语言普遍不擅长将不同类型处理为不同的、不兼容的事物。这是设计使然,因为他们应该轻松地将所有东西插入到所有东西中,并且可以证明是正确的。
所以,也许,一种语言至少具有一些检查类型的概念和工具会更好(例如 Python),或者使用实际上具有更严格的类型系统但不像 C、C++ 或 Rust 那样危险和难以编写的东西可能是可行的方法(例如 Go,但是我对此的经验为零)。
使用带有空格的 make 相当复杂
正确的。我对此没有什么可补充的,除了我认为 make 自 20 世纪 90 年代初以来就已经停滞不前,尽管它是一个至关重要的软件供应链元素,不幸的是不够稳健。
如今,您很少编写自己的 Makefile:有时您总是需要预构建配置系统来确定由该系统生成的编译器选项和库位置。如今,大多数此类系统都支持比 Makefile 作为构建工具的更少损坏的东西。我确实喜欢ninja
。CMake
以及meson
其他一些预构建配置框架支持生成开箱即用的 ninja 文件而不是 Makefile。所以就这么做吧。 (请注意,使用上述工具,它们可能会生成即使带有空格的文件也能工作的 Makefile,但这并不是一件非常可靠的事情;我亲眼目睹了 4 小时的汽车 Linux 发行版构建失败,因为 Make 更新意味着空格的规范方式可以插入 Make 变量已被删除。那天需要修复的开发人员赢得了我的很多尊重,并且一些调试帮助使他发现了该错误!)
使用文件名中的空格作为输入来测试程序,并在名称包含空格的目录中执行该程序及其测试套件。
是的,但同样,这只是“正常开发”,就像“不要假设文件名中的空格不会发生,为什么你会假设那样?!”。
因此,我对策略的主要看法是:
- 无论您做什么,都不要假设文件名中不会出现空格。这是一个虚假的假设,在你的职业生涯中从来都不是一个有效的假设。
- 避免使用具有相同假设的工具。