我认为bash在重音字符处理方式方面出现了一些异常。您可能想抢些爆米花,因为这会有点技术性...
Unicode允许某些重音字符以几种不同的方式表示:作为表示重音字符的“代码点”,或作为表示字符的无重音版本的一系列代码点,后跟重音。例如,“ä”既可以表示为U + 00E4(UTF-8 0xc3a4,带小写字母的拉丁小写字母1),也可以表示为U + 0061 U + 0308(UTF-8 0x61cc88,带小写字母的拉丁小写字母a +组合小写) )。
OS X的HFS +文件系统要求所有文件名都以其完全分解形式的UTF-8表示形式存储。在HFS +文件名中,“ä”必须编码为0x61cc88,而“ö”必须编码为0x6fcc88。
我很确定这里发生的事情是,当您在命令行中键入“Näyttökuva.png”时,它以预先合成的形式“键入”字符。创建文件后,文件系统将分解字符以进行存储。到目前为止一切都很好。但是,当您尝试使用以“Nä”开头的制表符补全时,我认为bash在搜索匹配项之前无法分解“ä”,当然也找不到任何东西。
为了说明不同之处,下面是一个示例,该示例说明了在命令行中仅键入“Näyttökuva.png”时使用的编码与将其存储为文件名并使用制表符补全来填充时使用的编码的示例:
$ printf Näyttökuva.png | xxd # This time I pasted the it in from this web page
0000000: 4ec3 a479 7474 c3b6 6b75 7661 2e70 6e67 N..ytt..kuva.png
$ touch Näyttökuva.png # Also pasted from the web
$ printf Näyttökuva.png | xxd # This time I tab-completed it after N
0000000: 4e61 cc88 7974 746f cc88 6b75 7661 2e70 Na..ytto..kuva.p
0000010: 6e67 ng
现在,关于删除和重新制表时字符丢失的问题,我怀疑这是密切相关的。具体来说,我认为bash每次按Delete键都会“删除”一个代码点,但是每次按一下从Terminal窗口中删除一个字符。因为其中一个删除的字符(这次为“ö”)由两个代码点组成,但是只有一个字符,所以终端显示不同步。尝试对整个文件名进行制表符填充,然后将其删除回“Näytt”,然后重新进行制表符填充:bash似乎认为仅删除了组合音符,而不是整个“ö”,因此它重新添加了组合音符,但这一次它附加到“ t”上:
$ echo Näytẗkuva.png
Näyttökuva.png
请注意,当我按回车键时,bash实际上具有整个文件名。只是终端显示感到困惑。
TL; DR bash在处理可分解带有重音符号的字符时存在一些错误。
编辑:经过一番思考,我认为唯一完整的解决方案是修复bash(/等待其开发人员对其进行修复)。也许还有一种以分解形式输入字符的方法,但是我不知道那是什么。但是我确实找到了一些解决方法:
从Finder中拖放文件会以正确的格式粘贴。由于Finder从文件系统获取文件名,因此它已经被分解,因此可以正常工作。
您实际上可以使用制表符完成重音字符本身。例如,如果您键入“ Na”,然后输入制表符,则它将匹配“Näyttökuva.png”,因为“ä”的规范分解以“ a”开始。但是,如果您在同一目录中有一个名为“ Narwal.gif”的文件,那将不会很有帮助...
我尚未对此进行测试,但是如果将Tab键绑定到菜单完成键而不是完整键,则应该让您选择可能的匹配项,以便即使您无法输入下一个字母也可以选择所需的匹配项。(或者您可以将其绑定到其他按键,因此只能在需要时使用它。)
为了解决终端显示不同步的问题,您可以将某些内容绑定到redraw-current-line上 -不会阻止问题的发生,但是它将为您提供一种重新同步显示的方法。
$ echo -e "N\xC3\xA4*" | ls
(回波给出Nä*
)结果Näyttökuva.png
。Mac OS中的其他外壳也存在该问题。与如zsh中ls N
得到自动完成ls Na<0308>ytto<0308>kuva.png