细嗦Linux单双引号

40 阅读2分钟

在其他编程语言中,双引号与单引号都表示字符串,几乎没什么区别。但是在shell中,单引号与双引号虽然也都表示字符串,但是在细微之处还有有区别

单引号字符:

  • 单引号的任何字符都会原样输出,单引号字符串中的变量是无效的
  • 单引号字符串中不能出现单独一个的单引号,对单引号使用转移也不行

双引号字符:

  • 字符中可以有变量
  • 允许解释美元符号、反符号、反斜杠

其实,双引号和单引号之间最直接的区别就是,双引号是先把字符串中能解释的先解释出来,再输出字符串;而单引号是直接把字符串原样输出。

看到这可能有人会说,那我全用双引号不就得了,想原样输出用转义字符转义一下不就行了,还跟其他编程语言习惯一样。其实,这样的想法在一般来说是没有什么问题的,但在一些特定场景下,就会在意想不到的地方给你意想不到的结果,比如:

$ echo  "1 2 3"|awk "{print $0}"
>> 0

在上述这个使用awk的例子中,为什么输出的不是1 2 3而是0?因为awk是一种单独的数据与文本处理语言,它使用的是自己单独的变量,而不是shell变量;所有在akw中如果你使用的是双引号包裹,那么变量就会变成shell变量,而不是awk变量,所以在awk中推荐使用单引号

上述的例子很好的解释了把双引号中所有能解释的用shell进行解释,除了这点外,双引号的使用还有一个值得注意的地方,那就是**“先解释后输出”**,什么意思?例如:

# remote_execute是一个登录到多主机的函数
# 这是用来登录到多主机执行命令的代码
# 本机名为node01
$ remote_execute "if [ `hostname` == "node01" ];then echo 1 > /data/zk/myid;fi"

你以为上面这个代码会在主机名为node01的机器上把1写到myid文件中,实际运行后,它会在所有主机上把1写到myid文件中。这是为什么?这就是双引号的**“先解释后输出”**。如果使用双引号,它会把hostname先在本机执行后,再把去所有机器上执行if。所以其实所有机器上执行的都是

if [ "node01" == "node01" ];then echo 1 > /data/zk/myid;fi

所以在执行命令的时候,应该多注意一下单引号与双引号的使用,以免出现不必要的错误。