判断
if -then
判断表达式是经常用到的。整体结构如下所示,其中if和fi是必须的,中间的elif和else是可选的。
if [ 判断条件1 ]; then
执行内容1
elif [ 判断条件2 ]; then
执行内容2
else
执行内容3
fi
case -esac
case $变量 in
"内容1")
程序1
;;
"内容2")
程序2
;;
*) #匹配其他所有情况
程序3
;;
esac
case $$1 in
"hello")
echo "hello world"
;;
"bye")
echo "bye bye"
;;
"*")
echo $1
;;
esac
循环
while -do -done
while [ condition ]
do
程序
done
until -do -done
在while循环中,当条件满足使,就执行其中的程序。而until循环中,当条件不成立时就终止循环。
until [ "$yn" == "yes" ]
do
read -p "Please input yes to stop: " yn
done
echo "Stop!"
for -do -done
for循环的格式如下
for var in con1 con2 con3 ...
do
程序
done
#下面这个示例循环打印输入参数列表
for arg in $*
do
echo $arg
done
Shell函数
echo "Before :" `printFunc`
function printFunc() {
echo "print function !"
}
echo "After :" `printFunc`
Shell 数组
- bash支持一维数组(不支持多维数组),并且没有限定数组的大小。
- 类似于 C 语言,数组元素的下标由 0 开始编号。获取数组中的元素要利用下标,下标可以是整数或算术表达式,其值应大于或等于 0。
定义数组
array_name=(value0 value1 value2 value3)
或者
array_name=(
value0
value1
value2
value3
)
还可以单独定义数组的各个分量:
array_name[0]=value0
array_name[1]=value1
array_name[n]=valuen
可以不使用连续的下标,而且下标的范围没有限制。
读取数组
${数组名[下标]}
例如:
valuen=${array_name[n]}
使用 @ 符号可以获取数组中的所有元素,例如:
echo ${array_name[@]}
### 获取数组的长度
获取数组长度的方法与获取字符串长度的方法相同,例如:
# 取得数组元素的个数
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得数组单个元素的长度
lengthn=${#array_name[n]}
多行注释
多行注释还可以使用以下格式:
:<<EOF
注释内容...
注释内容...
注释内容...
EOF
EOF 也可以使用其他符号:
:<<'
注释内容...
注释内容...
注释内容...
'
:<<!
注释内容...
注释内容...
注释内容...
!
正则表达式
正则表达式,又称规则表达式。(英语:Regular
Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念
正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本
许多程序设计语言都支持利用正则表达式进行字符串操作,例如,在Perl中就内建了一个功能强大的正则表达式引擎
正则表达式这个概念最初是由Unix中的工具软件(例如sed和grep)普及开的
正则表达式通常缩写成“regex”,单数有regexp、regex,复数有regexps、regexes、regexen
基本组成部分 | |
---|---|
\ | 转义符,将特殊字符进行转义,忽略其特殊意义 |
^ | 匹配行首,awk中,^则是匹配字符串的开始 |
$ | 匹配行尾,awk中,$则是匹配字符串的结尾 |
. | 匹配除换行符\n之外的任意单个字符,awk则中可以 |
[] | 匹配包含在[字符]之中的任意一个字符 |
[^] | 匹配[^字符]之外的任意一个字符 |
[-] | 匹配[]中指定范围内的任意一个字符,要写成递增 |
? | 匹配之前的项1次或者0次 |
+ | 匹配之前的项1次或者多次 |
* | 匹配之前的项0次或者多次 |
() | 匹配表达式,创建一个用于匹配的子串 |
{n} | 匹配之前的项n次,n是可以为0的正整数 |
{n,} | 之前的项至少需要匹配n次 |
{n,m} | 指定之前的项至少匹配n次,最多匹配m次, |
POSIX字符类 | |
---|---|
[:alnum:] | 匹配任意一个字母或数字字符 |
[:alpha:] | 匹配任意一个字母字符(包括大小写字母) |
[:blank:] | 空格与制表符(横向和纵向) |
[:digit:] | 匹配任意一个数字字符 |
[:lower:] | 匹配小写字母 |
[:upper:] | 匹配大写字母 |
[:punct:] | 匹配标点符号 |
[:space:] | 匹配一个包括换行符、回车等在内的所有空白符 |
[:graph:] | 匹配任何一个可以看得见的且可以打印的字符 |
[:xdigit:] | 任何一个十六进制数(即:0-9,a-f,A-F) |
[:cntrl:] | 任何一个控制字符(ASCII字符集中的前32个字符) |
[:print:] | 任何一个可以打印的字符 |
元字符
元字符(meta character)是一种Perl风格的正则表达式,只有一部分文本处理工具支持它,并不是所有的文本处理工具都支持。
\b | 单词边界 |
\B | 非单词边界 |
\d | 单个数字字符 |
\D | 单个非数字字符 |
\w | 单个单词字符(字母、数字与_) |
\W | 单个非单词字符 |
\n | 换行符 |
\s | 单个空白字符 |
\S | 单个非空白字符 |
\r | 回车 |
\v | 垂直制表符 |
\f | 换页符 |
expect
yum install expect
expect 是自动应答命令用于交互式命令的自动执行
spawn 是 expect 中的监控程序,其运行后会监控命令提出的交互问题
send发送问题答案给交互命令
"\r"表示回车
exp_continue 标示当问题不存在时继续回答下面的问题
expect eof 标示问题回答完毕退出 expect 环境
interact标示问题回答完毕留在交互界面
set NAME [ lindex $argv n ]定义变量
实现交互问答
vim ask.sh #编写提问脚本
#!/bin/bash
read -p "what's your name:" NAME
read -p "how old are you:" AGE
read -p "what's the best object to you:" OBJ
read -p "are you happy:" FEEL
echo $NAME is $AGE years study $OBJ feel $FEEL
#执行
sh ask.sh
实现脚本问答
vim answer.sh #编写回答脚本
#!/bin/bash
sh ask.sh <<-EOF
bob
22
linux
happy
EOF
#执行
sh answer.sh
实现灵活问答
如果提问脚本少了一个问题或者其他原因和回答脚本不一致,需要通过expect来实现灵活问答
vim answer.exp
#!/bin/bash
set timeout 5
set NAME [ lindex $argv 0 ]
set AGE [ lindex $argv 1 ]
set OBJ [ lindex $argv 2 ]
set FEEL [ lindex $argv 3 ]
spawn sh ask.sh
expect {
"name" { seng "$NAME\r" ; exp_continue }
"old" { seng "$AGE\r" ; exp_continue }
"object" { seng "$OBJ\r" ; exp_continue }
"happy" { seng "$FEEL\r" ; exp_continue }
}
interact
sh answer.sh #执行