Win 与 Unix 的几个字符区别
某些字符在 Win 端和 Unix 端有着不同的涵义,这是由它们各自发展的历史原因所导致的。
正斜杠与反斜杠
正斜杠 / 的英文是 forward slash 或者直接 slash,而反斜杠 \ 的英文名是 backward slash 也即 backslash。
在 Unix 类的计算机中,一般都是用像 MJ 一样向前倾的正斜杠 / 来表示目录,而反斜杠 \ 则一般用于表示转义字符。
然而在 Windows 早期的 Dos 中,正斜杠 / 却被用作命令参数的提示符,所以只好使用反斜杠 \ 来表示目录分隔符。不过随着 Windows 的发展,现在的 cmd 已经不再区分正反斜杠了。
所幸除了 Windows 这么特立独行外,其他大多数计算机资源都采用类 Unix 的标准,所以在网络 URL 中,我们仍然使用正斜杠 / 来表示目录分隔符。
对于熟悉 Linux 的人来说,用 - 作为参数提示符似乎是天经地义的事,然而在早期的 Dos 系统中,会使用正斜杠 \ 作为参数提示符,不过这个问题就要追溯到 IBM 的时代了,算是一个历史遗留问题吧。不过显然微软也意识到了这个问题,所以在 PowerShell 中也开始使用 - 来作为参数提示符了。
在 Unix 的设计里,反斜杠 \ 应该是不常出现的一个字符,通常情况下它被用来表示转义,转义既指去除 \ 后单个字符的特殊含义,仅将其作为字面上的一个字符,比如我们可以规定 \r 表示回车,使用反斜杠加一个空格表示这个空格仅仅是一个空格,而不是某些命令的分隔符之类。但如果反斜杠 \ 之后紧跟一个换行,那么这种转义的作用将被延续,直到下一个换行出现。
以下是一些例子
# 打印特殊字符
> echo $LANG
en_US.UTF-8
# 作为普通字符打印
> echo \$LANG
$LANG
# 打印普通字符
> echo \n
n
# 打印一个换行
> echo \\n
# 打印多行字符
> echo \
> \hello\
> world
helloworld
回车与换行
如果你对上面说的转义字符很熟悉,你就会发现回车与换行这两个特殊的字符。
回车 \r 本义是光标重新回到本行的开头,r 取自英文 return,控制字符是 CR,即 Carriage Return。
换行 \n 本义是让光标直接往下一行移动,n 取自英文 newline,控制字符是 LF,即 Line Feed。
下面是两个关于这两个字符的例子
# 使用 \r 覆盖掉 hello
> echo "hello \r world"
world
# 打印一个换行
> echo "\n"
>
本来回车与换行这两个概念来自于打字机,打字机用这两个字符来控制击打字样的位置,计算机继承了这两个概念,但问题在于如何继承这两个概念并没有统一。
Windows 保留了回车与换行这两个概念,所以可以理解为每行的结尾都是以 \r\n 作为结束符。但 Unix 和 Mac 的设计者认为使用两个字符结尾太浪费存储空间了,所以 Unix 使用了 \n 作为结束符,而 Mac 则使用 \r 作为结束符。所以在 Windows 中创建的文件在 Linux/Mac 中打开可能会在行尾多出一个 ^M,在 Git 中还有一个专门的设置用来解决这总不兼容的冲突。