jes*_*e_b 8 special-characters shell-script quoting
不知何故,大引号进入了我的代码,我得到了意想不到的行为
\n#!/bin/sh\n\nif [ foo = \xe2\x80\x98foo\xe2\x80\x99 ]; then\n echo yes\nelse\n echo no\nfi\n
Run Code Online (Sandbox Code Playgroud)\n我希望这会回显 yes,但实际上却回显 no。
\njes*_*e_b 22
弯引号或 \xe2\x80\x9csmartquotes\xe2\x80\x9d 用于排版,“直引号”通常会被各种文字处理程序自动更改为弯引号。它们有时被称为“智能引号”,因为它们在某种程度上智能地确定引用文本的方向并向其卷曲。
\n以下是各种报价的表格:
\n特点 | 描述 | 视窗/Unix | 苹果系统 | 超文本标记语言 |
---|---|---|---|---|
\' | 直接单引号 | \' | \' | \' |
” | 直双引号 | " | " | " |
\xe2\x80\x98 | 打开单引号 | alt+0145 | option+] | ‘ |
\xe2\x80\x99 | 结束单引号 | alt+0146 | option+ shift+] | ’ |
\xe2\x80\x9c | 打开双引号 | alt+0147 | option+[ | “ |
\xe2\x80\x9d | 结束双引号 | alt+0148 | option+ shift+[ | ” |
然而,在编程语言中,这些引号是不可互换的。直引号通常是在语言中执行特定功能的特殊字符,而外观相似的弯引号不被认为是特殊的。相反,它们可能会产生错误,或者可能被视为与字母有点相似的普通字符。
\n因此,在这个问题的代码示例中,大引号被视为它们的文字字符,而不仅仅是 shell 转义字符,因此\'foo\'
不匹配\'\xe2\x80\x98foo\xe2\x80\x99\'
为了防止出现此问题,您应该仅在专为代码编辑而设计的程序中编辑代码,并小心从任何文字处理应用程序(LibreOffice Word、写字板、电子邮件等)、PDF 文档或在线代码源复制代码。
\n弯引号和直引号之间的视觉区别可能很小,但通常可以区分。弯引号通常显示为倾斜的,或者类似于微型 6 或 9,具体取决于字体。
\n类似的程序od
也可用于区分常规 ASCII 直引号和 Unicode 弯引号。例如,以下文本文件的\xe2\x80\x9cfoo\xe2\x80\x9d
一行上带有大引号,"foo"
另一行上带有直引号,并且在 UTF-8 语言环境中,输出为od -c
显示大引号占用多个字节,而直引号则占用多个字节只取一个:
mac$ od -c test.txt\n0000000 \xe2\x80\x9c ** ** f o o \xe2\x80\x9d ** ** \\n " f o o " \\n\n0000020\n\ngnu$ od -c test.txt\n0000000 342 200 234 f o o 342 200 235 \\n " f o o " \\n\n0000020\n
Run Code Online (Sandbox Code Playgroud)\n(在上图中,macOS 在od
第一个位置显示完整字符,并用 标记字符的其余字节**
,而在下图中,GNUod
以八进制显示字符中所有字节的值。)