背景
波浪号替换仅发生在 Tcl 即将将字符串解释为文件名的位置,并且仅在字符串的第一个字符为 a 时发生~
(如果该字符在其他任何地方,则纯粹是正常的)。恰好有两个替换完成:
- 如果
~
是单独的或后跟目录分隔符,则它指的是您的主目录(嗯,严格来说是HOME
环境变量中命名的目录,默认为您的主目录)。
- 如果
~
后面有任何其他内容,则文件名的其余部分直到字符串末尾或第一个目录分隔符(以先到者为准)被解释为用户名,并且该~user
序列被该用户的主目录替换(查找使用系统实用程序,如/etc/passwd
Unix 等中所列)
这些功能在安全解释器中被禁用,即使用interp create -safe
或使用创建的解释器safe::interpCreate
。
解决方法
阻止前导~
成为问题的最简单方法是放在./
它前面,并始终使用-directory
选项 to glob
(否则,这是 Tcl 中唯一可以产生这些类型的文件名模棱两可的地方;可能是其他任何地方)。在整个过程中使用完整的文件名通常会减少整体问题(我建议尽可能不要更改工作目录;这只会导致巨大的混乱)。
我不认为安全解释器是一种解决方法,因为它们还有许多其他受限功能(例如,默认情况下根本无法访问文件系统)。
政策问题
至于应该可以禁用它的建议……这是一个有趣的建议,但从未在 Tcl 的指导委员会中认真提出过。问题是有很多代码假设当前行为;我认为添加一个hack(例如,一个不支持的魔法变量)来关闭它不会是一个特别的问题——在扩展完成的时候有一个解释器上下文,所以检查一个Tcl变量来看看是否做这是微不足道的——但我个人非常担心这种变化会意外破坏什么。
Stack Overflow 不是讨论此类更改的好环境。你最好在tcl-core mailing list上询问。请注意,有时这是一个相当强大的辩论室(尽管几乎总是礼貌)。另一种选择(如果你喜欢 IRC)是在 freenode 上的 #tcl 上询问。