快速解决方案
不要在键盘上使用重音字母,而是使用tab-complete(并设置SSH密钥,以便tab-complete也适用于网络scp,rsync等)或者回退到外卡,因为你经历的是什么是正常的预期行为.
它不起作用,因为您没有键入相同的文件名.
好像很疯狂?那是你的UTF-8.
更加疯狂:我可以使用我神奇的遥远的心灵阅读心灵力量告诉你,你有一台Apple Mac.
更严重的是:这是您在提出问题时忘记提供的重要信息,但是在输入问题时您不小心泄露了这些信息.
在复制粘贴上面的答案时:
# echo "scp me@example.com:/home/me/co?mmo?n_file.jpg" | hexdump -C
00000000 73 63 70 20 6d 65 40 65 78 61 6d 70 6c 65 2e 63 |scp me@example.c|
00000010 6f 6d 3a 2f 68 6f 6d 65 2f 6d 65 2f 63 6f cc 88 |om:/home/me/co..|
00000020 6d 6d 6f cc 88 6e 5f 66 69 6c 65 2e 6a 70 67 20 |mmo..n_file.jpg |
00000030 2f 68 6f 6d 65 2f 6d 65 2f 0a |/home/me/.|
0000003a
请密切关注字母’?’的编码方式:6f cc 88.附加’o’后跟一个额外的UTF-8代码点. (事实上??,在我的终端上,它甚至不显示为’?’而是显示为’o’)
当我(= Linux用户)输入时:
echo /home/me/c?mm?n_file.jpg | hexdump -C
00000000 2f 68 6f 6d 65 2f 6d 65 2f 63 c3 b6 6d 6d c3 b6 |/home/me/c..mm..|
00000010 6e 5f 66 69 6c 65 2e 6a 70 67 0a |n_file.jpg.|
0000001b
再仔细看看’?’符号:c3 b6,一个完全不同的UTF-8代码点,没有额外的litteral ASCII.
更长的解释:
在Unicode中,有多种方法可以代码为“?”.
>第一种方式是组成字符:有一个代码点,它是从Latin-1(ISO / IEC 8859-1:1998)代码点继承而来的,Unicode代码点U 00f6(在UTF-8中编码为c3 b6)
>第二种方式是分解字符:首先输出ASCII o,然后附加一个特殊代码点that means ‘Please combine an umlaut to the preceding letter‘,Unicode代码点U 0308(在UTF-8中编码为cc 88)
它的这个组合字符,使你做所有疯狂的狗屎一样?Z??a?l?g?o?和所有其他的黑暗怪物那潜伏在疯狂的疯狂怪异可憎的是UTF-8.
哼.
地球的其余部分尽可能使用组合字符(因为它更紧凑,并且因为它使用与Latin-1兼容的Unicode范围,简化了向后兼容性)并且只使用组合字符来处理没有它们的东西自己的代码点(大多数频率较低的语言).
苹果显然生活在一个不同的星球上,他们决定他们总是尝试使用组合角色(因为他们崇拜黑暗领主Za????l???????g?????????????o????????????????????).
键入看起来像’?’的键盘字母根本不会生成相同的二进制序列,具体取决于您键入键的计算机.
然后发挥另一个作用:大多数Unix倾向于使用文件系统(如Linux’EXT4),这些文件系统对大小写敏感且对Unicode编码敏感(支持UTF-8).他们试图保留文本的组成与否.因此,即使它们编码相同的最终结果’?’,它们也会区分UTF-8二进制序列6f cc 88和c3 b6. (以同样的方式区分’A’和’a’,即使它是相同的拉丁字母).
所以你的键盘产生的’?’和服务器上的’?’是不一样的.
碰巧堆栈交换只是存储你按原样抛出的任何Unicode编码,导致像HTML RegEx parser那样的神话答案. (因此你的Mac背叛了记录’?’的特定字节序列.