SHELL编程
目录:
shell介绍
Shell 是一个 C 语言编写的脚本语言,它是用户与 Linux 的桥梁,用户输入命令交给 Shell 处理,Shell 将相应的操作传递给内核(Kernel),内核把处理的结果输出给用户。
shell以及其他脚本语言
shell适合用处理操作系统底层业务,因为有大量的系统命令支撑,特别是grep,sed和awk,例如一键安装,优化和监控报警等,这样比较符合运维的大原则,高效。 而php和python优势在于运维和开发,web管理工具以及web业务开发,但是开发效率和复杂度都会过高。
shell编程的基础
- vi/vim编辑器的使用,ssh终端和.vimrc的设置
- linux常用命令熟练使用
- linux场景服务的部署和排错
shell分类
- Bourne shell
- sh,ksh,bash和sh
- C shell
- csh和tcsh
shell三种执行方式
- bash和sh
- 全路径和./
- source和.
[root@why sh]# cat test.sh
user=`whoami`
[root@why sh]# cat ex.sh
sh /root/sh/test.sh
echo $user
[root@why sh]# sh ex.sh
[root@why sh]# vi ex.sh
[root@why sh]# cat ex.sh
. /root/sh/test.sh
echo $user
[root@why sh]# sh ex.sh
root
一个shell脚本调用另一个脚本的参数需要引入,即source和.
shell注释
单行注释
#!/bin/bash
是指定执行脚本的时候通过那个程序来解析脚本的内容,'#!'称为幻数,这一行必须在脚本的顶端第一行,如果不是就内核就会认为是注释。其他行就可用#注释。
多行注释
: '
语句1
语句2
'
if false; then
语句1
语句2
fi
: << 字符
语句1
语句2
字符(在这个字符与上一个字符相同)
((0)) & {
语句1
语句2
}
清空日志的三种方式
echo > access.log
> access.log
cat /dev/null > access.log
有关单引号,双引号和无引号的区别
单引号:将单引号中的内容,原封不动的进行输出 双引号:把双引号中的内容输出,如果内容中有反引号命令,变量,特殊转义符等,会把这些解析出来再输出 无引号:把内容输出,当含有空格就无法进行输出
shell脚本
清空一个message文件
cd /var/log
cat /dev/null > message
echo 'Message cleaned up'
这样一个简单的脚本就完成了,但是会有很多很多的问题,例如需要root权限才能删除
[why@why root]$ > /var/log/messages
bash: /var/log/messages: Permission denied
我们就需要对此进行判断
LOG_DIR=/var/log
ROOT_UID=0
if [ "$UID" -ne "ROOT_UID" ]
then
echo 'Must be root to run this script'
exit 1
if
cd $LOG_DIR || {
echo 'Cannot to change dir' > &2
exit 1
}
cat /dev/null > message && echo 'Message clean up'
shell规范和习惯
- 开头表明解释器
- 添加一些创建时间,创建者信息,版权,描述等
- 关键步骤添加注释,但是不要用中文,防止乱码
- 脚本以sh为扩展名
- 脚本成对出现的括号流程控制一次性写完
- 缩进提高可读性
Shell变量
系统变量
在命令行提示符直接执行env、set查看系统变量。env是显示用户环境变量,set是显示Shell 变量。set变量可以通过export导入到env系统变量。 shell的环境变量可以在命令行生成,但是用户登出这些变量就会消失,一般在家目录下的.bash_profile,/etc/profile和/etc/profile.d/中定义,当用户登录时会自动加载,一般环境变量均为大写,并且用export命令导出(也可以用declare -x),这些一般被称为全局变量,写在脚本的即为局部变量,取消环境变量用unset环境变量。
$SHELL | 默认Shell |
---|---|
$HOME | 当前用户家目录 |
$IFS | 内部字段分隔符 |
$LANG | 默认语言 |
$PATH | 默认可执行程序路径 |
$PWD | 当前目录 |
$UID | 当前用户ID |
$USER | 当前用户 |
$HISTSIZE | 历史命令大小,可通过HISTTIMEFORMAT变量设置命令执行时间 |
$RANDOM | 随机生成一个0至32767的整数 |
$HOSTNAME | 主机名 |
shell特殊变量
$SHELL | 描述 |
---|---|
$0 | 获取当前shell脚本的文件名,如果全路径执行的话包括脚本路径 |
$n | shell脚本的第n个参数,如果n大于9就要括起来,例如${10} |
$* | 获取shell的所有参数,所有的位置参数被看做一个字符串,$1$2$3$4... |
$# | 获取参数的总个数,这个一般用于判断参数个数 |
$@ | 获取shell的所有参数,每个位置参数被看做独立的字符串,$1 $2 $3 $4... |
$$ | 当前shell进程的pid,一般用于一个脚本只能运行一个进程 |
$! | 上一个指令的pid |
$_ | 在此之前执行的命令或脚本的最后一个参数 |
$? | 上一个命令的返回值 |
shell变量子串
man bash查找Parameter Expansion
$SHELL | 描述 | |
---|---|---|
${#parameter} |
$parameter字符串长度 | |
${parameter:offset} |
在$parameter中, 从位置$offset开始提取子串 | |
${parameter:offset:length} |
在$parameter中, 从位置$offset开始提取长度为$length的子串 | |
${parameter#word} |
从变量$parameter的开头, 删除最短匹配$word的子串 | |
${parameter##word} |
从变量$parameter的开头, 删除最长匹配$sword的子串${parameter%word} | 从变量$parameter的结尾, 删除最短匹配$word的子串 |
${parameter%%word} |
从变量$parameter的结尾, 删除最长匹配$word的子串 | |
${parameter/pattern/replacement} |
使用$replacement, 来代替第一个匹配的$pattern | |
${parameter//pattern/replacement} |
使用$replacement, 代替所有匹配的$pattern | |
${parameter/#pattern/replacement} |
如果$parameter的前缀匹配$pattern, 那么就用$replacement来代替匹配到的$pattern | |
${parameter/%pattern/replacement} |
如果$parameter的后缀匹配$pattern, 那么就用$replacement来代替匹配到的$substring |
[root@why ~]# WHY="I am whywhy"
[root@why ~]# echo $WHY
I am whywhy
[root@why ~]# echo ${#WHY}
11
[root@why ~]# echo ${WHY:2}
am whywhy
[root@why ~]# echo ${WHY:2:8}
am whywh
[root@why ~]# echo ${WHY/why/wanghongyu}
I am wanghongyuwhy
[root@why ~]# echo ${WHY/%why/wanghongyu}
I am whywanghongyu
[root@why ~]# echo ${WHY#w*y}
I am whywhy
[root@why ~]# echo ${WHY##w*y}
I am whywhy
[root@why ~]# echo ${WHY%%w*y}
I am
[root@why ~]# echo ${WHY%w*y}
I am why
${parameter/%pattern/replacement}可用于后缀转换mv $f ${f%jpg/png}
常用变量状态赋值
$SHELL | 描述 |
---|---|
${value:-word} |
如果value不存在用word代替,在yum安装httpd的时候,/etc/init.d/httpd中就有 |
${value:=word} |
用word替换value |
${value:?word} |
用于捕捉变量为定义的错误,如果value没有,会提示word |
${value:+word} |
用于测试变量是否存在,返回值为word |
[root@why pythontest]# VAR=
[root@why pythontest]# echo ${VAR:-'hello world!'}
hello world!
[root@why pythontest]# VAR="hello"
[root@why pythontest]# echo ${VAR:+'hello world!'}
hello world!
[root@why pythontest]# VAR=
[root@why pythontest]# echo ${VAR:=hello}
hello
[root@why pythontest]# echo $VAR
hello
[root@why pythontest]# VAR=
[root@why pythontest]# echo ${VAR:?value is null}
-bash: VAR: value is null
对变量的路径进行操作时,最好先判断路径是否为非空,如下path变量没有定义,则取/tmp,防止变量没定义误删除:
$ find ${path-/tmp} -type f -name *.tar.gz -mtime +7 | xargs rm -f
后边这些与上述部分重复,仅供参考
表达式 | 含义 |
---|---|
${var} |
变量var的值, 与$var相同 |
${var-DEFAULT} |
如果var没有被声明, 那么就以$DEFAULT作为其值 |
${var:-DEFAULT} |
如果var没有被声明, 或者其值为空, 那么就以$DEFAULT作为其值,判断var变量是否没有定义 |
${var=DEFAULT} |
如果var没有被声明, 那么就以$DEFAULT作为其值 |
${var:=DEFAULT} |
如果var没有被声明, 或者其值为空, 那么就以$DEFAULT作为其值 ,判断var变量是否没有定义,并确保变量始终有值 |
${var+OTHER} |
如果var声明了, 那么其值就是$OTHER, 否则就为null字符串 |
${var:+OTHER} |
如果var被设置了, 那么其值就是$OTHER, 否则就为null字符串 |
${var?ERR_MSG} |
如果var没被声明, 那么就打印$ERR_MSG |
${var:?ERR_MSG} |
如果var没被设置, 那么就打印$ERR_MSG |
${!varprefix*} |
匹配之前所有以varprefix开头进行声明的变量 |
${!varprefix@} |
匹配之前所有以varprefix开头进行声明的变量 |
字符串颜色
字符串输出颜色,有时候关键地方需要醒目,颜色是最好的方式 格式: \033[1;31;40m # 1 是显示方式,可选。31 是字体颜色。40m 是字体背景颜色。 \033[0m # 恢复终端默认颜色,即取消颜色设置
代号 | 字体颜色 |
---|---|
30 | 黑 |
31 | 红 |
32 | 绿 |
33 | 黄 |
34 | 蓝色 |
35 | 紫色 |
36 | 深绿 |
37 | 白色 |
代号 | 字体背景颜色 |
---|---|
40 | 黑 |
41 | 深红 |
42 | 绿 |
43 | 黄色 |
44 | 蓝色 |
45 | 紫色 |
46 | 深绿 |
47 | 白色 |
代号 | 显示方式 |
---|---|
0 | 终端默认设置 |
1 | 高亮显示 |
4 | 下划线 |
5 | 闪烁 |
7 | 反白显示 |
8 | 隐藏 |
[root@why ~]# cat color.sh
#!/bin/bash
# 字体颜色
for i in {31..37}; do
echo -e "\033[$i;40mHello world!\033[0m"
done
# 背景颜色
for i in {41..47}; do
echo -e "\033[47;${i}mHello world!\033[0m"
done
# 显示方式
for i in {1..8}; do
echo -e "\033[$i;31;40mHello world!\033[0m"
done
表达式和运算符
条件表达式
表达式 | 示例 |
---|---|
[ expression ] | [ 1 -eq 1 ] |
[[ expression ]] |
[[ 1 -eq 1 ]] |
test expression | test 1 -eq 1 ,等同于[] |
整数比较符
比较符 | 描述 | 示例 |
---|---|---|
-eq,equal | 等于 | [ 1 -eq 1 ]为 true |
-ne,not equal | 不等于 | [ 1 -ne 1 ]为 false |
-gt,greater than | 大于 | [ 2 -gt 1 ]为 true |
-lt,lesser than | 小于 | [ 2 -lt 1 ]为 false |
-ge,greater or equal | 大于或等于 | [ 2 -ge 1 ]为 true |
-le,lesser or equal | 小于或等于 | [ 2 -le 1 ]为 false |
字符串比较符
运算符号 | 描述 | 示例 |
---|---|---|
== | 等于 | [ "a" == "a" ]为 true |
!= | 不等于 | [ "a" != "a" ]为 false |
> | 大于,判断字符串时根据ASCII码表顺序,不常用 | 在[]表达式中:[ 2 > 1 ]为true,在[[]]表达式中:[[ 2 > 1 ]]为true,在(())表达式中:(( 3 > 2 ))为true |
< | 小于,判断字符串时根据ASCII码表顺序,不常用 | 在[]表达式中:[ 2 \< 1 ]为 false,在[[]]表达式中:[[ 2 < 1 ]]为false,在(())表达式中:(( 3 < 2 ))为false |
>= | 大于等于 | 在(())表达式中:(( 3 >= 2 ))为true |
<= | 小于等于 | 在(())表达式中:(( 3 <= 2 ))为false |
-n | 字符串长度不等于0为真 | VAR1=1;VAR2="" [ -n "$VAR1" ]为true,[ -n "$VAR2" ]为false |
-z | 字符串长度等于0为真 | VAR1=1;VAR2=""[ -z "$VAR1" ]为false[ -z "$VAR2" ]为true |
str | 字符串存在为真 | VAR1=1;VAR2=""[ $VAR1 ]为true,[ $VAR2 ]为false |
文件测试
测试符 | 描述 | 示例 |
---|---|---|
-e | 文件或目录存在为真 | [ -e path ] path 存在为 true |
-f | 文件存在为真 | [ -f file_path ] 文件存在为 true |
-d | 目录存在为真 | [ -d dir_path ] 目录存在为 true |
-r | 有读权限为真 | [ -r file_path ] file_path 有读权限为 true |
-w | 有写权限为真 | [ -w file_path ] file_path 有写权限为 true |
-x | 有执行权限为真 | [ -x file_path ] file_path 有执行权限为 true |
-s | 文件存在并且大小大于0为真 | [ -s file_path ] file_path 存在并且大小大于 0为true |
布尔运算符
运算符 | 描述 | 示例 |
---|---|---|
! | 非关系,条件结果取反 | [ ! 1 -eq 2 ]为 true |
-a | 和关系,在[]表达式中使用 | [ 1 -eq 1 -a 2 -eq 2 ]为 true |
-o | 或关系,在[]表达式中使用 | [ 1 -eq 1 -o 2 -eq 1 ]为 true |
逻辑运算符
判断符 | 描述 | 示例 |
---|---|---|
&& | 逻辑和在[[]]和(())表达式中或判断表达式是否为真时使用 | [[ 1 -eq 1 && 2 -eq 2 ]]为 true(( 1 == 1 && 2 == 2 ))为true[ 1 -eq 1 ] && echo yes 如果&&前面表达式为 true 则执行后面的 |
||
为逻辑或,在[[]]和(())表达式中或判断表达式是否为真时使用,[[ 1 -eq 1 || 2 -eq 1 ]]
为true,(( 1 == 1 || 2 == 2 ))
为true,[ 1 -eq 2 ] || echo yes
如果||前面表达式为false则执行后面的
整数运算
运算符 | 描述 |
---|---|
+ | 加法 |
- | 减法 |
* | 乘法 |
/ | 除法 |
% | 取余 |
运算表达式 | 示例 |
---|---|
$(()) | $((1+1)) |
$[] | $[1+1] |
两个都不支持浮点运算,$(())表达式还有一个用途,三目运算 如果条件为真默认返回0,否则返回1
[root@why linux]# echo $((1<0))
0
[root@why linux]# echo $((1>0))
1
[root@why linux]# echo $((1>0?1:2))
1
[root@why linux]# echo $((1<0?1:2))
2
注意:自定义输出不支持字符串,只能指定数字
其他运算工具
命令 | 描述 | 示例 | |
---|---|---|---|
let | 赋值并运算,支持++、-- | let i=i+1 | |
expr | 乘法*需要加反斜杠转义* | expr ( 1 + 2) expr | |
bc | 计算器,支持浮点运算、平方等 | `echo "1.2+2" | bc` |
shell括号用途总结
括号 | 用途 | ||
---|---|---|---|
( ) | 用途1:在运算中,先计算小括号里面的内容;用途2:数组;用途3:匹配分组 | ||
(( )) | 用途1:表达式,不支持-eq这类的运算符。不支持-a和-o,支持<=、>=、<、>这类比较符和&&、 | ;用途2:C 语言风格的 for(())表达式 | |
$( ) | 执行shell命令,与漂号(``)等效 | ||
$(( )) | 用途1:简单算数运算;用途2:支持三目运算符$(( 表达式?数字:数字 )) | ||
[ ] | 条件表达式,里面不支持逻辑判断符 | ||
[[ ]] | 条件表达式,里面不支持-a和-o,不支持<=和>=比较符,支持-eq、<、>这类比较符。支持=~模式匹配,也可以不用双引号也不会影响原意,比[]更加通用 | ||
$[ ] | 简单算数运算 | ||
{ } | 对逗号(,)和点点(...)起作用,比如touch{1,2}创建1和2文件,touch{1..3}创建1、2和3文件${ } | 用途1:引用变量;用途2:字符串处理 |
流程控制
if
if list; then list; [ elif list; then list; ] ... [ else list; ] fi
单分支
if 条件表达式; then
命令
fi
双分支
if 条件表达式; then
命令
else
命令
fi
多分支
if 条件表达式; then
命令
elif 条件表达式; then
命令
else
命令
fi
for
正常风格
for 变量名 in 取值列表; do
命令
done
默认for循环的取值列表是以空白符分隔,如果想指定分隔符,可以重新赋值$IFS变量
#!/bin/bash
OLD_IFS=$IFS
IFS=":"
STR="12:34:45"
for i in $STR; do
echo $i
done
IFS=$OLD_IFS # 恢复默认值
c语言风格
for (( expr1 ; expr2 ; expr3 )) ; do list ; done
常用于计数、打印数字序列
#!/bin/bash
for ((i=1;i<=5;i++)); do # 也可以 i--
echo $i
done
while
while list; do list; done
while 条件表达式; do
命令
done
条件表达式为false会产生死循环
#!/bin/bash
while [ 1 -eq 1 ]; do
echo "yes"
与where类似的还有until,不过until为表达式为false时才循环,只需要在where判断的时候加个!即可达到until的效果
break和continue
break是终止循环,continue是跳出当前循环这两个只能通过循环使用
#!/bin/bash
N=0
while true; do
let N++
if [ $N -eq 5 ]; then
break
fi
echo $N
done
#!/bin/bash
N=0
while [ $N -lt 5 ]; do
let N++
if [ $N -eq 3 ]; then
continue
fi
echo $N
done
case
case语句一般用于选择性来执行对应部分块命令
case 模式名 in
模式 1)
命令
;;
模式 2)
命令
;;
*)
不符合以上模式执行的命令
esac
根据位置参数匹配不同的模式
#!/bin/bash
case $1 in
start)
echo "start."
;;
stop)
echo "stop."
;;
restart)
echo "restart."
;;
*)
echo "Usage: $0 {start|stop|restart}"
esac
很多的服务启动脚本就是这么实现的。 通过正则匹配
#!/bin/bash
case $1 in
[0-9])
echo "match number."
;;
[a-z])
echo "match letter."
;;
'-h'|'--help')
echo "help"
*)
echo "Input error!"
exit
esac
select
select是一个类似for循环的语句,一般用于菜单的制作
select 变量 in 选项 1 选项 2; do
break
done
示例
#!/bin/bash
select mysql_version in 5.1 5.6; do
echo $mysql_version
done
[root@why linux]# sh version.sh
1) 5.1
2) 5.6
#? 1
5.1
#? 2
5.6
#? ^C
写的更复杂一些
#!/bin/bash
PS3="Select a number: "
while true; do
select mysql_version in 5.1 5.6 quit; do
case $mysql_version in
5.1)
echo "mysql 5.1"
break
;;
5.6)
echo "mysql 5.6"
break
;;
quit)
exit
;;
*)
echo "Input error, Please enter again!"
break
esac
done
done
在外面加个死循环,每次执行一次select就break一次,这样就能每次显示菜单了,PS3代表提示符
函数与数组
函数
func() {
command
}
示例
#!/bin/bash
func() {
echo "This is a function."
}
func
[root@why ~]# bash test.sh
This is a function
函数返回值
#!/bin/bash
func() {
VAR=$((1+1))
return $VAR
echo "This is a function."
}
func
echo $?
[root@why ~]# bash test.sh
2
函数传参
#!/bin/bash
func() {
echo "Hello $1"
}
func world
[root@why ~]# bash test.sh
Hello world
数组
数组是相同类型的元素按一定顺序排列的集合,用小括号初始化数组,元素之间用空格分隔。 格式:array=(元素1 元素2 元素3 ...)
初始化数组
[root@why pythontest]# array=(a b c)
[root@why pythontest]# echo ${array[*]}
a b c
新建数组并添加元素
[root@why pythontest]# array[3]=d
[root@why pythontest]# echo ${array[*]}
a b c d
将命令输出作为数组元素
array=($(command))
获取元素下标
[root@why pythontest]# echo ${!array[@]}
0 1 2 3
获取数组长度
[root@why pythontest]# echo ${#array[*]}
4
添加多个元素
[root@why pythontest]# array+=(e f g)
[root@why pythontest]# echo ${array[*]}
a b c d e f g
删除第一个元素
[root@why pythontest]# unset array[0]
[root@why pythontest]# echo ${array[*]}
b c d e f g
删除数组
[root@why pythontest]# unset array
seq生成的数字序列循环放到数组里面
#!/bin/bash
for i in $(seq 1 10); do
array[a]=$i
let a++
done
echo ${array[*]}
遍历数组
#!/bin/bash
IP=(192.168.1.1 192.168.1.2 192.168.1.3)
for ((i=0;i<${#IP[*]};i++)); do
echo ${IP[$i]}
done
shell正则表达式
正则表达式在每种语言中都会有,目的就是匹配符合你预期要求的字符串,正则表达式又分为基础正则表达式:BRE(basic regular express)和扩展正则表达式:ERE(extend regular express),扩展的表达式有+、?、|和()
符号 | 描述 | 示例 | |||
---|---|---|---|---|---|
. | 匹配除换行符(\n)之外的任意单个字符 | 匹配 123:```echo -e "123\n456" | grep -E '1.3'``` | ||
^ | 匹配前面字符串开头 | 匹配以abc开头的行:`echo -e "abc\nxyz" | grep -E ^abc` | ||
$ | 匹配前面字符串结尾 | 匹配以xyz结尾的行:`echo -e "abc\nxyz" | grep -E xyz$` | ||
* | 匹配前一个字符零个或多个 | 匹配x、xo和xoo:`echo -e "x\nxo\nxoo\no\noo" | grep "xo*"`,x是必须的,批量了0零个或多个 | ||
+ | 匹配前面字符1个或多个 | 匹配 abc和abcc:`echo -e "abc\nabcc\nadd" | grep -E 'ab+'匹配单个数字: echo "113" |
grep -E -o '[0-9]'连续匹配多个数字: echo "113" |
grep -E -o '[0-9]+'` |
? | 匹配前面字符0个或1个匹配ac或abc: | `echo -e "ac\nabc\nadd" | grep -E 'a?c'` | ||
[ ] | 匹配中括号之中的任意一个字符 | 匹配a或c:`echo -e "a\nb\nc" | grep -E '[ac]'` | ||
[ .-.] | 匹配中括号中范围内的任意一个字符 | 匹配所有字母:`echo -e "a\nb\nc" | grep -E '[a-z]'` | ||
[^] | 匹配[^字符]之外的任意一个字符 | 匹配a或b:`echo -e "a\nb\nc" | grep -E '[^c-z]'匹配末尾数字: echo "abc:cde;123" |
grep -E'[^;]+$'` | |
{n}或{n,} | 匹配花括号前面字符至少n个字符 | 匹配abc字符串(至少三个字符以上字符串):`echo -e "a\nabc\nc" | grep -E '[a-z]{3}'` | ||
{n,m} | 匹配花括号前面字符至少n个字符,最多m个字符 | 匹配12和123(不加边界符会匹配单个字符):`echo -e "1\n12\n123\n1234" | grep -E -w -o '[0-9]{2,3}'` | ||
\< | 边界符,匹配字符串开始匹配 | 开始是 123 和 1234:`echo -e "1\n12\n123\n1234" | grep -E -w '\<123'` | ||
> | 边界符,匹配字符串结束 | 匹配结束是 1234:`echo -e "1\n12\n123\n1234" | grep -E '4>'` | ||
( ) | 单元或组合:将小括号里面作为一个组合 分组:匹配小括号中正则表达式或字符。\n反向引用,n是数字,从1开始编号,表示引用第n个分组匹配的内容 | 单元:匹配 123a 字符串`echo "123abc" | grep -E -o '([0-9a-z]){4}'分组:匹配 11 echo "113abc" |
grep -E -o '(1)\1'匹配出现xo出现零次或多次: echo -e "x\nxo\nxoo\no\noo" |
egrep "(xo)*"` |
` | ` | 匹配竖杠两边的任意一个 | 匹配12和123:`echo -e "1\n12\n123\n1234" | grep -E '12> | 123>'` |
\ | 转义符,将特殊符号转成原有意义 | 1.2,匹配 1.2:1.2,否则 112 也会匹配到 |
Posix字符 | 描述 |
---|---|
[:alnum:] | 等效[a-zA-Z0-9] |
[:alpha:] | 等效[a-zA-Z] |
[:lower:] | 等效[a-z] |
[:upper:] | 等效[A-Z] |
[:digit:] | 等效[0-9] |
[:space:] | 匹配任意空白字符,等效[\t\n\r\f\v] |
[:graph:] | 非空白字符 |
[:blank:] | 空格与定位字符 |
[:cntrl:] | 控制字符 |
[:print:] | 可显示的字符 |
[:punct:] | 标点符号字符 |
[:xdigit:] | 十六进制 |
空白符 | 描述 |
---|---|
\n | 换行符 |
\r | 回车符 |
\t | 水平制表符 |
\v | 垂直制表符 |
\0 | 空值符 |
\b | 退后一格 |