Unicode编码中的两种空格\u00A0和\u0020

遇到一个坑

今天有个朋友问我一个问题,说跟着一个Linux操作教程,复制粘贴没有出来同样的效果。
要是说这个命令是一个非常负责的操作,涉及到各种环境什么的我就认了,关键它是个常用的ll命令。

1
2
3
4
5
6
root@iZZ:/home# wget http://mirrors.shu.edu.cn/apache/tomcat/tomcat-8/v8.5.27/bin/apache-tomcat-8.5.27.tar.gz
root@iZZ:/home# cd test/
root@iZZ:/home/test# cp /home/apache-tomcat-8.5.27.tar.gz ./
root@iZZ:/home/test# tar -zxvf apache-tomcat-8.5.27.tar.gz
root@iZZ:/home/test# ll /home/test/ #这里出问题了!
bash: ll /home/test/: No such file or directory

看着这几命令,这兄弟完全不能相信自己的眼睛!“我是哪一步错了???”

不行,我再复制粘贴来几遍,但是还是同样的效果,刚好我去他家蹭饭,顺便问了下我。
我也是瞪着眼看着命令,都没有问题啊,我也蒙了一比!上手试试!!

1
2
3
4
5
6
root@iZZ:/home/test# ll /home/test/
total 9280
drwxr-xr-x 3 root root 4096 Jan 29 15:47 ./
drwxr-xr-x 4 root root 4096 Jan 29 15:41 ../
drwxr-xr-x 9 root root 4096 Jan 29 15:47 apache-tomcat-8.5.24/
-rw-r--r-- 1 root root 9487006 Jan 29 15:41 apache-tomcat-8.5.24.tar.gz

我要爬出来

好吧,怎么这么神奇,问题出在哪里呢???问题就在于这里:

1
2
3
4
5
6
7
8
root@iZZ:/home/test# ll /home/test/ #\u00A0
bash: ll /home/test/: No such file or directory
root@iZZ:/home/test# ll /home/test/ #\u0020
total 9280
drwxr-xr-x 3 root root 4096 Jan 29 15:47 ./
drwxr-xr-x 4 root root 4096 Jan 29 15:41 ../
drwxr-xr-x 9 root root 4096 Jan 29 15:47 apache-tomcat-8.5.24/
-rw-r--r-- 1 root root 9487006 Jan 29 15:41 apache-tomcat-8.5.24.tar.gz

\u00A0\u0020这两个Unicode编码都是表示的空格,前者是不间断空格,后者就是我们常用的半角空格。而还有一个全角空格是\u3000
在Linux上进行命令操作时,输入单个\u00A0\u0020的显示效果基本没有差异,肉眼基本无法识别,我也是把它们复制出来用编码转换才发现。
但是bash是不能将\u00A0解析成正常命令与参数之间的空格,最终导致命令识别错误,显示的结果也不对!

1
2
root@iZZ:/home/test# ll /home/test/ #\u3000
bash: ll /home/test/: No such file or directory

其他地方

我们也要注意在Java和JavaScript中,\u00A0\u0020的显示也是一样的,大家小心复制踩坑。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Test {
public static void main(String[] args) {
System.err.println("Hello\u00A0World"); //Hello World
System.err.println("Hello\u0020World"); //Hello World 常用
System.err.println("Hello\u3000World"); //Hello World
String spaceA = " ";
String spaceB = " ";
String spaceC = " ";
System.err.println(spaceA.equals(spaceB)); //false
System.err.println(spaceA.equals(spaceC)); //false
System.err.println(spaceB.equals(spaceC)); //false
System.err.println("\u00A0".equals(spaceA));//true
System.err.println("\u0020".equals(spaceB));//true
System.err.println("\u3000".equals(spaceC));//true
}
}

这样的问题在Javascript中也是有的,而且不同浏览器的处理方式还不一样!但是

1
2
3
alert(String.fromCharCode(112, 160, 108, 32, 97, 12288, 105, 110));
// 我试过过,在Win10上的Chrome 63.0.3239.132、Edge 41.16299.15.0和IE 11.192.6299.0显示效果都一样。
// 但是网上有人说“但是在IE里,\u00A0就不是显示空格,firefox里会显示空格,\u0020不管是firefox里,还是IE里都显示空格。”

参考文档