程序中的反单引号“ ` ”


【前言】

     学习工作中,反单引号“ ` ”这个东东在代码和程序中越来越常见了,因此专门小结一下。因个人学识有限,所以这里只记录亲身体验过的那一部分。另外,可以参考“ ` ”的百度百科词条http://baike.baidu.com/link?url=1okXapsQKMemThKADipScvdrZYfkk0mbgCRiiAAjXDps93SMXq0Gmjv4xflD_RhLwib_FlzsTtz-0toBndYs2q。正如词条所言,“ ` ”首先是我们一个中文汉字,此处高能小心狗眼,`就是决明,决明子相信很多人都有所耳闻,老一辈喜欢泡茶喝,大众化的中医神药之一了。当然,汉字“ ` ”不是要说的重点,以下主要以Linux Shell、SQL和Python中的“ ` ”展开。


【具体】

①Shell中的“ ` ”

     Linux Shell中“ ` ”是一个解释符,以“ ` ”括起来的内容会先被解释输出返回外层再接着执行剩下的命令。

[root@centos6-5 ~]# echo -e "My OS is:\n    `uname -a`"
My OS is:
    Linux centos6-5 2.6.32-431.el6.x86_64 #1 SMP Fri Nov 22 03:15:09 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux

     这种反单引号括包的形式简单易懂,但并不规范(POSIX)。一方面,当真正需要字符“ ` ”时就得通过额外的元字符“ \ ”转义;另一方面,Shell脚本中封装其他语言的代码时有潜在暗坑(互相“争用 ` ”的冲突)。

     为了Shell脚本的通用性,最好的习惯是避免使用(不用)“ ` ”,而以$(command)的形式替代`command`。

[root@centos6-5 ~]# echo -e "My OS is:\n    $(uname -a)"
My OS is:
    Linux centos6-5 2.6.32-431.el6.x86_64 #1 SMP Fri Nov 22 03:15:09 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux

②SQL中的“ ` ”

     “ ` ”是MySQL数据库的固有分隔符(括包库、表、字段等名称),在我们写SQL语句的时候,经常会用到或者忽略它的存在,这是一个类似于阳光、空气和雨露一样的东西,可省略、必需以及多余的情况都会出现。

mysql> create database csdn_blog;
Query OK, 1 row affected (0.00 sec)

mysql> drop database csdn_blog;
Query OK, 0 rows affected (0.00 sec)

mysql> create database `csdn_blog`;
Query OK, 1 row affected (0.01 sec)

     最一般和绝大多数的情况下,“ ` ”是可以省略的。

mysql> use csdn_blog;
Database changed
mysql> create table text_2016.09.15(`id` int(11), primary key(`id`));
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '.15(`id` int(11), primary key(`id`))' at line 1
mysql> create table `text_2016.09.15`(`id` int(11), primary key(`id`));
Query OK, 0 rows affected (0.03 sec)

     “ ` ”分隔符不可省略的情况。

student@ubuntu:~$ cat csdn_blog.sh 
# !/bin/bash
mysql -uroot -p520 <<EOF
    CREATE DATABASE IF NOT EXISTS `csdn_blog`;
EOF
echo "END!!!"
student@ubuntu:~$ bash csdn_blog.sh 
csdn_blog.sh: 行 2: csdn_blog: 未找到命令
mysql: [Warning] World-writable config file '/etc/mysql/mysql.conf.d/mysqld.cnf' is ignored.
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1064 (42000) at line 1: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
END!!!
student@ubuntu:~$ vim csdn_blog.sh 
student@ubuntu:~$ cat csdn_blog.sh 
# !/bin/bash
mysql -uroot -p520 <<EOF
    CREATE DATABASE IF NOT EXISTS csdn_blog;
EOF
echo "END!!!"
student@ubuntu:~$ bash csdn_blog.sh 
mysql: [Warning] World-writable config file '/etc/mysql/mysql.conf.d/mysqld.cnf' is ignored.
mysql: [Warning] Using a password on the command line interface can be insecure.
END!!!

     “ ` ”分隔符需要省略的情况(可以通过“\”转义)。

     对比可知,MySQL中只要不引起SQL语句检查错误,“ ` ”都是可以省略的;与此同时,系统保留的字符(如示例中的点号“ . ”)如果不用“ ` ”括起来,就会被截断解释而产生报错;然而,如果SQL被其他语言封装,同时“ ` ”作为该语言的解释符,额外的“ ` ”就会弄巧成拙画蛇添足,Shell和Python中都会有这种情况。

③Python中的“ ` ”

     Python中“ ` ”作为一个转换符,具有和repr()函数相同的功能,即string化数据。

Python 2.7.12 (default, Jul  1 2016, 15:12:24) 
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> say = 520
>>> type(say)
<type 'int'>
>>> type(repr(say))
<type 'str'>
>>> type(`say`)
<type 'str'>

     如同Shell中的情况,Python中“ ` ”也属于一种简写法,简写法在移植性等方面或多或少会产生一些问题,而在Python3中反单引号的写法就被干掉了。

Python 3.5.2 (default, Jul  5 2016, 12:43:10) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> say = 520
>>> type(say)
<class 'int'>
>>> type(repr(say))
<class 'str'>
>>> type(`say`)
  File "<stdin>", line 1
    type(`say`)
         ^
SyntaxError: invalid syntax

     所以,Python2代码移植到Python3环境,“ ` ”也会是一个潜在的问题。


【小结】

     从操作系统层面、到数据库、再到编程语言,都有反单引号“ ` ”这家伙的烙印,本文对它做了一些简单的列举。总结来看,除了SQL中有时候为了避免截断错误而必须要用到“ ` ”(应该尽可能规避SQL保留字符而做到完全弃用反单引号),其他时候都可以避免使用反单引号,这也是一种规范化。



版权声明:本文为sweeper_freedoman原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。