shell语言,一些字符是有特殊意义的。
根据作用分为几种特殊符号
一、空白
shell调用函数,不像c语言那样用把参数放到括号里,用逗号分隔。而是用空格作为参数之间,参数与函数名之间的分隔符。
换行符也是特殊字符。换行符用作一条命令与另一条命令的分隔符。
二、{}
{string1,string2,...} 逗号格式
会替换成多个字符串
$ echo d{a,e,i,u,o}g
dag deg dig dug dog
$ echo {cat,dog}
cat dog
大括号可以嵌套。
$ echo {j{p,pe}g,png}
jpg jpeg png
{start..end} 范围格式
{start..end}会替换成连续多个字符。
$ echo d{a..d}g
dag dbg dcg ddg
$ echo {11..15}
11 12 13 14 15
如果遇到无法解释的扩展,会原样输出。
$ echo {a1..3c}
{a1..3c}
这种格式可与逗号联用。
$ echo .{mp{3..4},m4{a,b,p,v}}
.mp3 .mp4 .m4a .m4b .m4p .m4v
因为空格是特殊字符,所以{}内不可使用空格,如果非要使用,那么要引用。
三、~
替换成用户主目录
四、变量替换$
因为字符串可以不带引号,所以变量名与字符串字面值区分不开,于是就有了$的特殊用途。
$把后面的单词统统当作变量,然后替换成变量的值。
shell内置变量
变量名 | 函数 |
---|---|
$FUNCNAME | 函数名称 |
$RANDOM | 随机数 |
$0 | 脚本名称 |
$n | 脚本位置参数,n是整数,10及以上表示为${10},shift进行偏移获取参数值 |
$@ | 所有位置参数 |
$* | 所有位置参数 |
$# | 位置参数的个数 |
$_ | 上一条命令最后一个参数 |
$? | 上条命令的返回值 |
$$ | 脚本的PID |
$PPID | 父进程ID |
$LINENO | 脚本执行的行号 |
$PWD | 当前目录 |
$SECONDS | 脚本已经运行的时间(s) |
$TMOUT | 超时退出时间(s) |
$UID | 当前用户ID |
自定义变量
var=value
$var
为了避免变量名与字符串连接在一起,变成一个错误变量名。可以使用${var}格式。
五、命令替换
`command`
把``中的字符串当成一条命令,执行命令,替换成命令的标准输出。
`ls`就是替换成ls的标准输出。
$()与``作用一样
六、运算替换
$(())替换成数字运算结果
七、通配符
英文叫wildcard,也叫globbing patterns。因为Unix早期有一个/etc/glob文件保存通配符模板,后来Bash内置了这个功能,但是这个名字被保留了下来。
通配符是由shell处理的,不是由命令处理的,也就是说,先由shell处理完,再把处理结果传给命令。
遇到通配符时,shell会将其当作路径或文件名去在磁盘上搜寻可能的匹配:若匹配存在,则替换成找到的路径;否则就将该通配符作为一个普通字符。
通配符:
字符 | 含义 | 实例 |
* | 匹配0或多个字符 但是不匹配斜杠/和开头的点 中间的点可以匹配 | a*b a与b之间可以有任意长度的任意字符, 也可以一个也没有, 如aabcb, axyzb, a012b, ab |
? | 匹配任意一个字符 但是不匹配斜杠/和开头的点 中间的点可以匹配 | a?b a与b之间必须也只能有一个字符, 可以是任意字符, 如aab, abb, acb, a0b |
[list] | 匹配list中的任意单一字符 | a[xyz]b a与b之间必须也只能有一个字符, 但只能是x或y或z, 如: axb, ayb, azb |
[!list] [^list] | 匹配 除list中的任意单一字符 | a[!0-9]b a与b之间必须也只能有一个字符, 但不能是阿拉伯数字, 如axb, aab, a-b |
[c1-c2] | 匹配c1-c2中的任意单一字符 | a[0-9]b 0与9之间必须也只能有一个字符 如a0b, a1b... a9b。 |
[[:class:]] | 匹配字符类中任意单一字符 | [:alnum:]:所有字母和数字 [:alpha:]:所有字母 [:digit:]:所有数字 [:lower:]:所有小写字母 [:upper:]:所有大写字母 [:blank:]:空白字符和TAB制表符 [:space:]:包括空白字符、TAB制表符(t)、换页(f) [:cntrl:]:所有控制字符 [:graph:]:可打印并可看到的字符。空格是可打印的,但是不是可看到的 [:print:]:所有可打印字符 [:punct:]:所有标点符号,非字母、数字、控制字符和space字符 [:xdigit:]:十六进制数的字符 注意:引用时,需要在加一层括号,如[[:alnum:]] |
通配符看起来像正则表达式,但它与正则表达式不同,不能相互混淆。
shell本身是不支持正则表达式的,支持正则表达式的一般是具体的命令,比如grep。
例子:
ls
a.txt b.txt c.old
ls *.txt
a.txt b.txt
ls d*.txt
ls: 无法访问d*.txt: 没有那个文件或目录
ls [[:alpha:]]*.txt
a.txt b.txt
在第2个命令中,*.txt实际shell搜索文件,找到了符合条件的文件,命令会变成:ls a.txt b.txt,实际在执行ls时候传给它的是a.txt b.txt
而命令3,d*.txt由于当前目录下面没有这样的文件或目录,直接将”d*.txt”作为ls参数,传给了ls。这个时候”*” 只是一个普通的ls参数而已,已经失去了它特殊意义。由于找不到文件,所以会出现无法访问提示!
大括号也可以与通配符联用。
$ echo {cat,d*}
cat dawg dg dig dog doug dug
上面代码中,会先进行大括号扩展,然后进行*扩展。
{}与[]有一个很重要的区别。如果匹配不到,[]就不替换,变成一个单纯的字符串,而{}依然替换。
# 不存在a.txt和b.txt
$ ls [ab].txt
ls: [ab].txt: No such file or directory
$ ls {a,b}.txt
ls: a.txt: No such file or directory
ls: b.txt: No such file or directory
上面代码中,如果不存在a.txt和b.txt,那么[ab].txt就会变成一个普通的文件名,而{a,b}.txt可以照样展开。
八、shell元字符
字 | |
= | 设定变量 |
> | 输出重定向 |
< | 输入重定向 |
| | 管道 |
& | 文件描述符复制 |
九、转义符
也叫引用
转义:就是转变原来意义的意思
有时候,我们想让通配符或者元字符变成普通字符,不需要使用它。那么这里我们就需要用到转义符了。
shell提供转义符有三种。
字符 | 说明 |
''(单引号) | 又叫硬转义,其内部所有的元字符、通配符都会被关掉。 |
""(双引号) | 又叫软转义,其内部只允许出现特定的元字符: 美元符$、反斜线\、反引号`依然保留其特殊用途 |
\(反斜杠) | 又叫转义,去除其后紧跟的元字符或通配符的特殊意义 |
ls \*.txt
ls: 无法访问 *.txt: 没有那个文件或目录
ls '*.txt'
ls: 无法访问 *.txt: 没有那个文件或目录
ls "*.txt"
ls: 无法访问 '*.txt': 没有那个文件或目录