case (打印菜单,使用case做出选择)
语法:
case var in ——定义变量
pattern 1) ——模式1; 用 | 分割多个模式,相当于or
执行语句1 ——需要执行的语句
;; ——结束
pattern 2)
执行语句2
;;
pattern 3)
执行语句3
;;
*) ——default,不满足以上模式,默认执行*)下面的语句
执行语句4
;;
esac
demo1:
当给程序传入start、stop、reload三个不同参数时分别执行相应命令。
#!/bin/bash
case $1 in
start|S)
echo "service is running..."
;;
stop|P)
echo "service is not running..."
;;
reload|R)
echo "service is reloading..."
;;
*)
echo "hello world"
;;
esac
demo2: 相互嵌套
#!/bin/bash
case $1 in
start|S)
echo "service is running..."
;;
stop|P)
read -p "Input your service:" name
case $name in
vsftpd|ftp)
service vsftpd start &>/dev/null
echo "ftp 服务已经启动"
;;
httpd|web)
service httpd restart &>/dev/null
echo "web 服务已经启动"
;;
*)
echo "请输入正确的服务名!"
;;
esac
;;
reload|R)
echo "service is reloading..."
;;
*)
echo "hello world"
;;
esac
demo3:
模拟一个多任务维护界面。当执行某程序时先显示总菜单,然后进行相应选择后进入子菜单。
如:
#!/bin/bash
echo "**************************"
echo "******欢迎进入总菜单********"
echo " 操作类型 "
echo " 1——系统 "
echo " 2——程序 "
echo " 3——数据库 "
echo " 0——退出 "
echo "**************************"
read -p "请选择操作类型:" choose
echo
case "$choose" in
0)
echo "谢谢使用,如有问题联系管理员:root@localhost"
;;
1)
echo "欢迎进入红帽子系统"
;;
2)
echo "程序维护"
;;
3)
clear
echo "*******欢迎来到子菜单*****"
echo "**********操作类型********"
echo " 1——备份 "
echo " 2——维护 "
echo " 3——优化 "
echo " 0——退出 "
echo "**************************"
read -p "请选择操作类型:" choose1
case "$choose1" in
1)
echo backup
;;
0)
echo "谢谢使用!"
;;
*)
echo "请选择操作类型"
;;
esac
;;
*)
echo "how are you?"
;;
esac
#!/bin/bash
case $1 in
hello)
echo world
;;
world)
echo hello
;;
*)
echo "$0 用法是:$0 hello or world"
;;
esac
函数
语法:
function_name() {
command
command
}
function function_name() {
command
command
}
demo:函数定义
# cat function.sh
#!/bin/bash
uplook()
{
echo "this is function uplook."
echo "hello $1."
return 终止一个函数
}
function hello()
{
echo "this is function hello."
echo "hi $1."
return
}
return两个作用。
1、用来返回一个值给函数,主函数调用这个函数后能得到这个返回的值。
2、用来结束函数,例如你运行到一个地方,虽然后面还有代码但是你不想再继续运行,这时你就可以直接用return;这条语句来结束函数
函数中的return命令返回函数中最后一个命令的退出状态或给定的参数值,该参数值的范围是0-256之间。如果没有return命令,函数将返回最后一个Shell的退出值。
函数调用:
source function.sh 或者. function.sh
1、在命令行进行调用:
# . function.sh
# uplook 888
this is function uplooking.
hi 888.
2、写到用户环境变量里:
uplook()
{
echo "this is function uplook."
echo "hello $1."
return
}
source .bash_profile
# uplook world
this is function hello.
hello world.
3、直接写到脚本里
demo:批量创建5个用户stu1~stu5,每个用户的附加组都为admin
使用函数:
#!/bin/bash
#定义创建用户和组的函数
function user()
{
for i in {1..5}
do
useradd -G admin stu$i
echo 123|passwd --stdin stu$i
done
}
group()
{
groupadd admin
}
#判断admin组是否存在
cut -d: -f1 /etc/group|grep -w admin >/dev/null 2>&1
#如果条件满足则直接调用创建用户的函数;否则先创建组再创建用户
[ $? -eq 0 ] && user || group && user
或者
[ $? -ne 0 ] && group && user ?
问题:在脚本中source一个函数再去调用,有问题?
练习:
1、输入一个等级(A-E),查看每个等级的成绩;如:输入A,则显示“90分~100分”,一次类推
2、模拟2人第一次相亲的场景,使用read让用户输入它的名字,性别,年龄(年龄放在性别判断后);在case里面再嵌套case菜单,使之选项更丰富。
要求:
1)对性别进行判断,如果不输入男或者女,则显示”你是泰国来的吗?“如果是男的,对其年龄进行判断。
2)如果男的年龄大于等于18岁则显示“某某先生,你结婚了吗?”;如果对方回答结了或者yes,则显示“结了你来这凑什么热闹”;如果对方回答没有或者no,再次询问“那你有房有车吗?”;如果既不说结了也不说没结则显示:“你Y的到底结没结婚啊?”如果回答有,则显示”咱去民政局领证吧“;如果回答没有,则显示“不好意思,我去下洗手间。”;如果既不说有又不说没有,则显示“别浪费时间,请正面回答”。如果男的年龄小于18岁,则显示“某某某你个小毛孩也来这凑热闹啦”
3)如果是女的,并且年龄大于等于18岁,则显示”某某女士你好“;否则显示”某某小姐你好“
*****************************************************************************************************
正则表达式:
正则表达式(英语:Regular Expression、regex或regexp,缩写为RE),也译为正
规表示法、常规表示法,指使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。
正则表达式这个概念最初是由Unix中的工具软件(例如sed和grep)普及开的。
正则表达式 <locate find vim grep sed awk>
第一类正则表达式:
前导字符(即位于元字符前面的字符);所谓元字符就是指那些 在正则表达式中具有特殊意义的专用字符
(1).: 任意单个字符,除了换行符
(2)*: 前导字符出现 0 次 或连续多次 go*gle g*le google ggle
(3).*: 任意长度的字符
(4)^: 行的开头
(5)$: 行的结尾
(6)^$: 空行
(7)[ ] 匹配指定字符组内的任一字符
(8)[^] 匹配不在指定字符组内的任一字符 [^abc]
(9)^[] 匹配以指定字符组内的任一字符开头 ^[abc]
(10)^[^] 匹配不以指定字符组内的任一字符开头 ^[^abc]
(11)\<: 取单词的头
(12)\>: 取单词的尾
(13)\<\> 精确匹配符号
(14)\{n\} {n} 匹配前面字符连续出现n次
(15)\{n,\} {n,} 匹配前面字符至少出现n次
(16)\{n,m\} {n,m} 匹配前面字符出现n次与m次之间
(17) \(\) 保存被匹配的字符
(18) + 前导字符连续出现一次或者多次
(19) ? 前导字符连续出现零次或者一次
\d 匹配数字 [0-9]
\w 匹配字母数字下划线[a-zA-Z0-9_]
\s 匹配空格、制表符、换页符[\t\r\n]
172.16.13.250
\(172.16.13\).250
\(172\.16\.13\)\.250 \1 \2 ... \9
sed -n 's/\(172\.16\.13\)\.250/\1\.110/p'
sed -n 's#\(172\.16\.13\)\.250#\1\.110#p' 1.txt
vim
:%s#\(172.16.13.\)250#\1110#g
sed -n 's/\(hello\) my\(self\)/\1 your\2/p' 1.txt
将192.168.0.254 换成 192.168.1.254
# sed -n 's/\(192\.168\)\.0\.254/\1\.1\.254/'
找出含有192.168的行,同时保留192.168并标记为标签1,之后可以使用\1来引用它。最多可以定义9个标签,从左边开始编号,最左边的是第一个。
将helloworld yourself 换成hellolilei myself
# sed -n 's/\(hello\)world your\(self\)/\1lilei my\2/p' 1.txt
hellolilei myself
扩展类的正则表达式 grep -E | egerp
匹配包含root或者ftp或者adm行
# grep "root|ftp|adm" /etc/passwd
# egrep "root|ftp|adm" /etc/passwd
# grep -E 'o+gle' test.txt
# grep -E 'o?gle' test.txt
# grep -P '\d' test.txt
# grep -P '\w' test.txt
# grep -P '\s' test.txt
通配符和正则表达式相应符号的区别:
正则表达式 *(匹配0或多个前字符) ?(匹配0或1个前字符)
通配符 *(匹配 0 或多个任意字符) ?(匹配任意单个字符)
shell转义符:
有时候,我们想让 通配符,或者元字符变成普通字符,不需要使用它。 shell提供转义符有三种。
''(单引号) 又叫硬转义,其内部所有的shell 元字符、通配符都会被关掉。注意,硬转义中不允许出现’(单引号)。
""(双引号) 又叫软转义,其内部只允许出现特定的shell 元字符:$用于参数代换 `用于命令代替
\(反斜杠) 又叫转义,去除其后紧跟的元字符或通配符的特殊意义。
第二类正则表达式(POSIX标准):
大写 [[:upper:]] [A-Z]
小写 [[:lower:]] [a-z]
字母 [[:alpha:]] [a-Z]
字母数字 [[:alnum:]]
制表符 [[:blank:]]
空格 [[:space:]]
纯数字 [[:digit:]] [0-9]
标点符号 [[:punct:]]
[[:alnum:]]: 字母数字 [0-9a-zA-Z]
练习:
文件grep.txt:
# cat grep.txt
Aieur45869Root0000
9h847RkjfkIIIhello
rootHllow88000dfjj
8ikuioerhfhupliooking
hello world
192.168.0.254
welcome to uplooking.
abcderfkdjfkdtest
rlllA899kdfkdfj
iiiA848890ldkfjdkfj
abc
1、查找不以大写字母开头 的行(三种写法)。
2、查找有数字的行(两种写法)
3、查找一个数字和一个字母连起来的行
4、查找不以r开头的行
5、查找以数字开头的
6、查找以大写字母开头的
7、查找以小写字母开头的
8、查找以点结束的
9、去掉空行
10、查找完全匹配abc的行
11、查找到A后有三个数字的行
12、统计root在/etc/passwd里出现了几次
13、用正则表达式找出自己的IP地址、广播地址、子网掩码
# ifconfig eth0|grep Bcast|grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}'
# ifconfig eth0|grep Bcast|grep -o '\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}'
\d
# ifconfig eth0|grep Bcast|grep -P -o '\d+\.\d+\.\d+\.\d+'
# ifconfig eth0|grep Bcast|grep -P -o '(\d+\.){3}\d+'
14、找出文件中的ip地址并且打印替换成172.16.2.254
# sed -n 's#\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}#172.16.12.254#p' 11.txt
# sed -n 's#192.168.0.\(254\)#172.16.12.\1#p' 11.txt
15、找出文件中的ip地址
grep --help:
匹配模式选择:
Regexp selection and interpretation:
-E, --extended-regexp 扩展正则
-F, --fixed-strings PATTERN is a set of newline-separated fixed strings
-G, --basic-regexp 基本正则
-P, --perl-regexp 调用perl的正则
-e, --regexp=PATTERN use PATTERN for matching
-f, --file=FILE obtain PATTERN from FILE
-i, --ignore-case 忽略大小写
-w, --word-regexp 匹配整个单词
-x, --line-regexp 匹配正行
-z, --null-data a data line ends in 0 byte, not newline
预习:sed
语法:
case var in ——定义变量
pattern 1) ——模式1; 用 | 分割多个模式,相当于or
执行语句1 ——需要执行的语句
;; ——结束
pattern 2)
执行语句2
;;
pattern 3)
执行语句3
;;
*) ——default,不满足以上模式,默认执行*)下面的语句
执行语句4
;;
esac
demo1:
当给程序传入start、stop、reload三个不同参数时分别执行相应命令。
#!/bin/bash
case $1 in
start|S)
echo "service is running..."
;;
stop|P)
echo "service is not running..."
;;
reload|R)
echo "service is reloading..."
;;
*)
echo "hello world"
;;
esac
demo2: 相互嵌套
#!/bin/bash
case $1 in
start|S)
echo "service is running..."
;;
stop|P)
read -p "Input your service:" name
case $name in
vsftpd|ftp)
service vsftpd start &>/dev/null
echo "ftp 服务已经启动"
;;
httpd|web)
service httpd restart &>/dev/null
echo "web 服务已经启动"
;;
*)
echo "请输入正确的服务名!"
;;
esac
;;
reload|R)
echo "service is reloading..."
;;
*)
echo "hello world"
;;
esac
demo3:
模拟一个多任务维护界面。当执行某程序时先显示总菜单,然后进行相应选择后进入子菜单。
如:
#!/bin/bash
echo "**************************"
echo "******欢迎进入总菜单********"
echo " 操作类型 "
echo " 1——系统 "
echo " 2——程序 "
echo " 3——数据库 "
echo " 0——退出 "
echo "**************************"
read -p "请选择操作类型:" choose
echo
case "$choose" in
0)
echo "谢谢使用,如有问题联系管理员:root@localhost"
;;
1)
echo "欢迎进入红帽子系统"
;;
2)
echo "程序维护"
;;
3)
clear
echo "*******欢迎来到子菜单*****"
echo "**********操作类型********"
echo " 1——备份 "
echo " 2——维护 "
echo " 3——优化 "
echo " 0——退出 "
echo "**************************"
read -p "请选择操作类型:" choose1
case "$choose1" in
1)
echo backup
;;
0)
echo "谢谢使用!"
;;
*)
echo "请选择操作类型"
;;
esac
;;
*)
echo "how are you?"
;;
esac
#!/bin/bash
case $1 in
hello)
echo world
;;
world)
echo hello
;;
*)
echo "$0 用法是:$0 hello or world"
;;
esac
函数
语法:
function_name() {
command
command
}
function function_name() {
command
command
}
demo:函数定义
# cat function.sh
#!/bin/bash
uplook()
{
echo "this is function uplook."
echo "hello $1."
return 终止一个函数
}
function hello()
{
echo "this is function hello."
echo "hi $1."
return
}
return两个作用。
1、用来返回一个值给函数,主函数调用这个函数后能得到这个返回的值。
2、用来结束函数,例如你运行到一个地方,虽然后面还有代码但是你不想再继续运行,这时你就可以直接用return;这条语句来结束函数
函数中的return命令返回函数中最后一个命令的退出状态或给定的参数值,该参数值的范围是0-256之间。如果没有return命令,函数将返回最后一个Shell的退出值。
函数调用:
source function.sh 或者. function.sh
1、在命令行进行调用:
# . function.sh
# uplook 888
this is function uplooking.
hi 888.
2、写到用户环境变量里:
uplook()
{
echo "this is function uplook."
echo "hello $1."
return
}
source .bash_profile
# uplook world
this is function hello.
hello world.
3、直接写到脚本里
demo:批量创建5个用户stu1~stu5,每个用户的附加组都为admin
使用函数:
#!/bin/bash
#定义创建用户和组的函数
function user()
{
for i in {1..5}
do
useradd -G admin stu$i
echo 123|passwd --stdin stu$i
done
}
group()
{
groupadd admin
}
#判断admin组是否存在
cut -d: -f1 /etc/group|grep -w admin >/dev/null 2>&1
#如果条件满足则直接调用创建用户的函数;否则先创建组再创建用户
[ $? -eq 0 ] && user || group && user
或者
[ $? -ne 0 ] && group && user ?
问题:在脚本中source一个函数再去调用,有问题?
练习:
1、输入一个等级(A-E),查看每个等级的成绩;如:输入A,则显示“90分~100分”,一次类推
2、模拟2人第一次相亲的场景,使用read让用户输入它的名字,性别,年龄(年龄放在性别判断后);在case里面再嵌套case菜单,使之选项更丰富。
要求:
1)对性别进行判断,如果不输入男或者女,则显示”你是泰国来的吗?“如果是男的,对其年龄进行判断。
2)如果男的年龄大于等于18岁则显示“某某先生,你结婚了吗?”;如果对方回答结了或者yes,则显示“结了你来这凑什么热闹”;如果对方回答没有或者no,再次询问“那你有房有车吗?”;如果既不说结了也不说没结则显示:“你Y的到底结没结婚啊?”如果回答有,则显示”咱去民政局领证吧“;如果回答没有,则显示“不好意思,我去下洗手间。”;如果既不说有又不说没有,则显示“别浪费时间,请正面回答”。如果男的年龄小于18岁,则显示“某某某你个小毛孩也来这凑热闹啦”
3)如果是女的,并且年龄大于等于18岁,则显示”某某女士你好“;否则显示”某某小姐你好“
*****************************************************************************************************
正则表达式:
正则表达式(英语:Regular Expression、regex或regexp,缩写为RE),也译为正
规表示法、常规表示法,指使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。
正则表达式这个概念最初是由Unix中的工具软件(例如sed和grep)普及开的。
正则表达式 <locate find vim grep sed awk>
第一类正则表达式:
前导字符(即位于元字符前面的字符);所谓元字符就是指那些 在正则表达式中具有特殊意义的专用字符
(1).: 任意单个字符,除了换行符
(2)*: 前导字符出现 0 次 或连续多次 go*gle g*le google ggle
(3).*: 任意长度的字符
(4)^: 行的开头
(5)$: 行的结尾
(6)^$: 空行
(7)[ ] 匹配指定字符组内的任一字符
(8)[^] 匹配不在指定字符组内的任一字符 [^abc]
(9)^[] 匹配以指定字符组内的任一字符开头 ^[abc]
(10)^[^] 匹配不以指定字符组内的任一字符开头 ^[^abc]
(11)\<: 取单词的头
(12)\>: 取单词的尾
(13)\<\> 精确匹配符号
(14)\{n\} {n} 匹配前面字符连续出现n次
(15)\{n,\} {n,} 匹配前面字符至少出现n次
(16)\{n,m\} {n,m} 匹配前面字符出现n次与m次之间
(17) \(\) 保存被匹配的字符
(18) + 前导字符连续出现一次或者多次
(19) ? 前导字符连续出现零次或者一次
\d 匹配数字 [0-9]
\w 匹配字母数字下划线[a-zA-Z0-9_]
\s 匹配空格、制表符、换页符[\t\r\n]
172.16.13.250
\(172.16.13\).250
\(172\.16\.13\)\.250 \1 \2 ... \9
sed -n 's/\(172\.16\.13\)\.250/\1\.110/p'
sed -n 's#\(172\.16\.13\)\.250#\1\.110#p' 1.txt
vim
:%s#\(172.16.13.\)250#\1110#g
sed -n 's/\(hello\) my\(self\)/\1 your\2/p' 1.txt
将192.168.0.254 换成 192.168.1.254
# sed -n 's/\(192\.168\)\.0\.254/\1\.1\.254/'
找出含有192.168的行,同时保留192.168并标记为标签1,之后可以使用\1来引用它。最多可以定义9个标签,从左边开始编号,最左边的是第一个。
将helloworld yourself 换成hellolilei myself
# sed -n 's/\(hello\)world your\(self\)/\1lilei my\2/p' 1.txt
hellolilei myself
扩展类的正则表达式 grep -E | egerp
匹配包含root或者ftp或者adm行
# grep "root|ftp|adm" /etc/passwd
# egrep "root|ftp|adm" /etc/passwd
# grep -E 'o+gle' test.txt
# grep -E 'o?gle' test.txt
# grep -P '\d' test.txt
# grep -P '\w' test.txt
# grep -P '\s' test.txt
通配符和正则表达式相应符号的区别:
正则表达式 *(匹配0或多个前字符) ?(匹配0或1个前字符)
通配符 *(匹配 0 或多个任意字符) ?(匹配任意单个字符)
shell转义符:
有时候,我们想让 通配符,或者元字符变成普通字符,不需要使用它。 shell提供转义符有三种。
''(单引号) 又叫硬转义,其内部所有的shell 元字符、通配符都会被关掉。注意,硬转义中不允许出现’(单引号)。
""(双引号) 又叫软转义,其内部只允许出现特定的shell 元字符:$用于参数代换 `用于命令代替
\(反斜杠) 又叫转义,去除其后紧跟的元字符或通配符的特殊意义。
第二类正则表达式(POSIX标准):
大写 [[:upper:]] [A-Z]
小写 [[:lower:]] [a-z]
字母 [[:alpha:]] [a-Z]
字母数字 [[:alnum:]]
制表符 [[:blank:]]
空格 [[:space:]]
纯数字 [[:digit:]] [0-9]
标点符号 [[:punct:]]
[[:alnum:]]: 字母数字 [0-9a-zA-Z]
练习:
文件grep.txt:
# cat grep.txt
Aieur45869Root0000
9h847RkjfkIIIhello
rootHllow88000dfjj
8ikuioerhfhupliooking
hello world
192.168.0.254
welcome to uplooking.
abcderfkdjfkdtest
rlllA899kdfkdfj
iiiA848890ldkfjdkfj
abc
1、查找不以大写字母开头 的行(三种写法)。
2、查找有数字的行(两种写法)
3、查找一个数字和一个字母连起来的行
4、查找不以r开头的行
5、查找以数字开头的
6、查找以大写字母开头的
7、查找以小写字母开头的
8、查找以点结束的
9、去掉空行
10、查找完全匹配abc的行
11、查找到A后有三个数字的行
12、统计root在/etc/passwd里出现了几次
13、用正则表达式找出自己的IP地址、广播地址、子网掩码
# ifconfig eth0|grep Bcast|grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}'
# ifconfig eth0|grep Bcast|grep -o '\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}'
\d
# ifconfig eth0|grep Bcast|grep -P -o '\d+\.\d+\.\d+\.\d+'
# ifconfig eth0|grep Bcast|grep -P -o '(\d+\.){3}\d+'
14、找出文件中的ip地址并且打印替换成172.16.2.254
# sed -n 's#\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}#172.16.12.254#p' 11.txt
# sed -n 's#192.168.0.\(254\)#172.16.12.\1#p' 11.txt
15、找出文件中的ip地址
grep --help:
匹配模式选择:
Regexp selection and interpretation:
-E, --extended-regexp 扩展正则
-F, --fixed-strings PATTERN is a set of newline-separated fixed strings
-G, --basic-regexp 基本正则
-P, --perl-regexp 调用perl的正则
-e, --regexp=PATTERN use PATTERN for matching
-f, --file=FILE obtain PATTERN from FILE
-i, --ignore-case 忽略大小写
-w, --word-regexp 匹配整个单词
-x, --line-regexp 匹配正行
-z, --null-data a data line ends in 0 byte, not newline
预习:sed