shell中的引号使用

Linux 中引号使用

由于对bash中的特殊符号不太了解,导致在使用命令或写脚本时总觉得有些错误莫名其妙,有些结果不如人所愿,几经尝试,不断百度,才能得到想要的结果。因此将刚刚遇到的问题进行查阅整理,以便加强记忆。 在进行一些linux命令操作时,经常使用正则表达式,对输出结果进行过滤,如存在如下文件:

# i am comment
i am normal line

希望通过正则表达式,只输出第二行,将第一行的注释行过滤:

cat test | grep -P ^(?!#)
运行结果:
cat test | grep -P ^(?cat test | grep -P ^(?)
-bash: 未预期的符号 `(' 附近有语法错误

查找失败,命令运行失败。而以同样的方式,过滤掉非注释行,只输出注释行:

cat test | grep -P ^#
运行结果:
# i am comment

则运行成功,能够正常查找到注释行。因为非注释行的正则表达式(不以'#'字符开头):

^(?!#)

中含有特殊字符!#,被bash或sh解释器重新解释,因此grep收到的正则表达式不是我们预想输入的结果。因此执行:cat test | grep -P ^(?!#)会不是预想的结果,甚至报错。根据错误提示,可以知道,bash将!#解释成之前的字符串,即cat test | grep -P ^(?。 特殊符号参考

鉴于上述情况,可以使用引号来解决问题,接下来介绍常用的三种引号:单引号,双引号,外引号。

1. 单引号

单引号括起来的所有字符,均作为普通字符处理,引号内禁止变量扩展。即bask等解释器不会关注单引号中的字符形式,不会对单引号中的字符进行重新解释。因此可以使用单引号解决上面的过滤非注释行的问题。修改为:

cat test | grep -P '^(?!#)'
运行结果:
i am normal line

符合预期

2. 双引号

部分引用,引号内可以进行符号扩展,$(美元符号)、"(双引号)、\(反斜线)均保留其特殊功能:

$: 取变其后指定变量的值来代替变量和$符号,当变量与相邻的字符有其他含义时,需要使用{}将变量名括起来,作为一个整体。
\: 转义符号,使解释器将转义符后的字符按照普通字符处理,不进行扩展。
": 部分引用,想在双引号中引用 " ,需要在其前面加上 \ 转义符号。

有时为保持变量的完整性,不想被空格扩展为多个参数时,需要将完整变量使用双引号括起来:

#!/bin/bash
function func1()
{
    echo $1
}
function func2()
{
    func1 $1
}

func2 "hello func"
运行结果:
hello

与预期的hello func不符,原因是在func2中调用func1中时,解释器将调用fun1的参数按照空格分隔成多个参数,如果想保持参数的完整性,则:

#!/bin/bash
function func1()
{
    echo $1
}
function func2()
{
    func1 "$1"
}

func2 "hello func"
运行结果:
hello func

3. 反引号

反引号内的字符串被解释成命令行,bash解释器将命令行的执行输出结果,替换反引号及其包含的部分,因此大多是右值,将命令的输出结果赋值给其他变量:

test_string=`echo $HOME`
echo $test_string
运行结果:
/home/pateo

还能使用双引号,将多个命令的输出结果组成一个字符串:

test_string="`echo $HOME`+`ls .`"
echo $test_string
运行结果:
/home/pateo+test

4. $()

与反引号作用相同,反引号是老的用法,而$()是新用法,推荐使用。

test_string=$(echo $HOME)
echo $test_string
运行结果:
/home/pateo

posted on 2020-03-14 23:36  guoyw  阅读(1681)  评论(0编辑  收藏  举报

导航