case分支结构
语法及特点
- 检查变量的实际取值
- 如果与预设的值相匹配,则执行对应的操作
- case分支,功能类似if,但不如if强大,有时语句比if精简
case结构
case 变量 in ##通常用于位置变量,用于编写小工具
模式1)
执行指令1 ;;
模式2)
执行指令2 ;;
.. ..
*)
执行指令3
esac
case分支的执行流程
编写一个简单的case分支的脚本
[root@proxy mnt]# vim test01.sh
#!/bin/bash
#这是一个case分支用法的简单测试脚本
case $1 in
a)
echo "AAA";;
b)
echo "BBB";;
*)
echo "请输入a或者b"
esac
[root@proxy mnt]# bash test01.sh
请输入a或者b
[root@proxy mnt]# bash test01.sh a
AAA
[root@proxy mnt]# bash test01.sh b
BBB
[root@proxy mnt]# bash test01.sh c
请输入a或者b
--------------------------------------------------------------------------------
[root@proxy mnt]# vim test02.sh
#!/bin/bash
#这是一个简单的文档操作的测试脚本,注:此脚本是在相对路径执行
case $1 in
t|T) ##
touch $2;;
m|M)
mkdir $2;;
r|R)
rm -rf $2;;
*)
echo "请输入t|m|r"
esac
[root@proxy mnt]# bash test02.sh
请输入t|m|r
[root@proxy mnt]# bash test02.sh t ##由于此脚本是两个位置变量,少输入一个就会报错
touch: 缺少了文件操作数
Try 'touch --help' for more information.
[root@proxy mnt]# bash test02.sh t abc ##创建abc文件
[root@proxy mnt]# ls
abc test01.sh test02.sh
[root@proxy mnt]# bash test02.sh m 123 ##创建123目录
[root@proxy mnt]# ls
123 abc test01.sh test02.sh
[root@proxy mnt]# bash test02.sh r 123 ##删除123目录
[root@proxy mnt]# ls
abc test01.sh test02.sh
编写一键部署nginx软件的脚本
[root@proxy opt]# bash test15.sh ##此脚本是根据相对路径而进行编辑
#!/bin/bash
#这是一个自动部署nginx的软件的测试脚本
yum -y install gcc openssl-devel pcre-devel &> /dev/null ##下载依赖包
cd lnmp_soft
tar -xf nginx-1.12.2.tar.gz -C /opt
cd /opt/nginx-1.12.2
./configure &> /dev/null
make && make install &> /dev/null
#systemctl stop firewalld ##安装有防火墙就需要这一步,没有则不需要
/usr/local/nginx/sbin/nginx
[root@proxy opt]# bash test15.sh
[root@proxy opt]# ss -ntulp |grep :80
tcp LISTEN 0 128 *:80 *:*
users:(("nginx",pid=3379,fd=6),("nginx",pid=3378,fd=6))
--------------------------------------------------------------------------------
[root@server0 opt]# vim 1.sh
#!/bin/bash
#这是一个自动部署nginx的软件的测试脚本,
rpm -q expect
if [ $? -eq 0 ];then
expect << EOF
set timeout 2
spawn scp -r student@172.25.0.250:/linux-soft/02/lnmp_soft.tar.gz /opt
expect "(yes/no)"
send "yes\r"
expect "passwd:"
send "tedu\r" ##请参考实际情况填写密码
expect eof
EOF
yum -y install gcc openssl-devel pcre-devel &> /dev/null ##下载依赖包
tar -xf /opt/lnmp_soft.tar.gz -C /opt
cd /opt/lnmp_soft
tar -xf nginx-1.12.2.tar.gz -C /opt
cd /opt/nginx-1.12.2
./configure &> /dev/null
make && make install &> /dev/null
#systemctl stop firewalld ##安装有防火墙就需要这一步
/usr/local/nginx/sbin/nginx
else
echo "请下载expect软件" && exit
fi
利用case分支编写一个控制nginx的脚本
[root@proxy opt]# vim test02.sh
#!/bin/bash
#这是一个简单的控制nginx服务脚本
case $1 in
start|s) ##控制nginx开启服务
netstat -ntulp | grep -q nginx
[ $? -eq 0 ] && echo "nginx已经开启了" && exit
/usr/local/nginx/sbin/nginx;;
stop|p) ##控制nginx关闭服务
netstat -ntulp | grep -q nginx
[ $? -ne 0 ] && echo "nginx已经关闭了" && exit
/usr/local/nginx/sbin/nginx -s stop;;
restart|res) ##控制nginx重启服务
/usr/local/nginx/sbin/nginx -s stop
/usr/local/nginx/sbin/nginx;;
net|n)
netstat -ntulp | grep -q nginx
[ $? -eq 0 ] && echo "nginx服务已开启" || echo "nginx服务未开启";;
*)
echo "请输入s|p|res|n"
esac
[root@proxy2 opt]# bash test02.sh n
nginx服务未开启
[root@proxy2 opt]# bash test02.sh s
[root@proxy2 opt]# bash test02.sh n
nginx服务已开启
[root@proxy2 opt]# bash test02.sh s
nginx已经开启了
[root@proxy2 opt]# bash test02.sh p
[root@proxy2 opt]# bash test02.sh p
nginx已经关闭了
shell中色彩处理
shell脚本中echo显示内容带颜色显示,echo显示带颜色,需要使用参数-e
- 格式1: echo -e “\033[背景颜色;文字颜色m 要输出的字符 \033[0m”
- 格式2:echo -e “\e[背景颜色;文字颜色m要输出的字符\e[0m”
控制选项:
\033[0m 关闭所有属性 (恢复默认)
\033[1m 设置高亮度,加粗
\033[5m 闪烁
不输出\033[0m的效果的话1级提示符会根据设置的颜色而改变
30~39前景色
40~49背景色
50~59高亮色
90~99高亮色
[root@proxy opt]# echo -e "\033[42;34mABCD\033[0m"
ABCD (蓝色字体,绿色背景)
[root@proxy opt]# echo -e "\e[42;34mABCD\e[0m"
ABCD (效果同上)
注:其中42的位置代表底色,34的位置代表的是字的颜色,0m是清除所有格式
1、字背景颜色和文字颜色之间是英文的分号";"
2、文字颜色后面有个m
3、字符串前后可以没有空格,如果有的话,输出也是同样有空格
4、echo显示带颜色,需要使用参数-e ,-e 允许对下面列出的加反斜线转义的字符进行解释.
给上面那个脚本加上色彩
[root@proxy opt]# vim test02.sh
#!/bin/bash
#这是一个简单的控制nginx服务脚本
case $1 in
start|s)
netstat -ntulp | grep -q nginx
[ $? -eq 0 ] && echo -e "\033[31m nginx已经开启了\033[0m" && exit
/usr/local/nginx/sbin/nginx;;
stop|p)
netstat -ntulp | grep -q nginx
[ $? -ne 0 ] && echo -e "\033[32m nginx已经关闭了\033[0m" && exit
/usr/local/nginx/sbin/nginx -s stop;;
restart|res)
/usr/local/nginx/sbin/nginx -s stop
/usr/local/nginx/sbin/nginx;;
net|n)
netstat -ntulp | grep -q nginx
[ $? -eq 0 ] && echo -e "\033[33m nginx服务已开启\033[0m" || echo -e "\033[34m nginx服务未开启\033[0m";;
*)
echo "请输入s|p|res|n"
esac
shell函数
什么是函数?
- 在shell环境中,将一些需要重复使用的操作,定义为公共的语句块,即可称为函数
- 即,函数, 可以将公共的语句块提前定义好,调用时仅使用函数名,达到精简脚本的目的
使用函数的好处? - 使脚本代码更简洁,增强易读性
- 提高shell脚本的执行效率
服务脚本中的函数应用 - 适用于比较复杂的启动/终止控制操作
- 方便在需要时的多次调用
函数的定义与调用
调用已定义的函数
- 格式: 函数名
- 先定义了才能调用,就好比脚本的"内部命令"
函数传值 - 格式: 函数名 值1 值2
- 传递的值作为函数的"位置参数"
函数的定义方法
function 函数名 { ##格式1
命令序列
.. ..
}
--------------------------------------------------------------------------------
函数名() { ##格式2
命令序列
.. ..
}
函数的调用
直接使用“函数名”的形式调用,如果该函数能够处理位置参数,则可以使用“函数名 参数1 参数2 … …”的形式调用。
注意:函数的定义语句必须出现在调用之前,否则无法执行。
[root@proxy opt]# a() {
> echo 123
> ls
> }
[root@proxy opt]# a
123
ceph.sh lnmp_soft nginx-1.12.2 test02.sh
lnmp.sh lnmp_soft.tar.gz test01.sh test03.sh
利用shell的色彩处理写一个函数的脚本
[root@proxy opt]# vim test04.sh
#!/bin/bash
haha() {
echo -e "\033[$1m$2\033[0m"
}
haha 32 窗前明月光
haha 33 疑是地下霜
haha 34 举头望明月
haha 35 低头思故乡
[root@proxy opt]# bash test04.sh ##此为案例显示,实际看操作效果
窗前明月光
疑是地下霜
举头望明月
低头思故乡
编写一个函数脚本
[root@proxy ~]# vim myping.sh
#!/bin/bash
#这是一个pingIP地址的函数脚本
myping(){
ping -c1 -W1 $1 &>/dev/null
if [ $? -eq 0 ];then
echo "$1 is up"
else
echo "$1 is down"
fi
}
for i in {1..254}
do
myping 192.168.4.$i &
done
wait #wait命令的作用是等待所有后台进程都结束才结束脚本。
exit 终止脚本.默认的返回值是0
break 终止循环,继续循环之后的任务(跳出当前所在的循环体,执行循环体后的语句块)
continue 终止当前循环,继续下一次循环(跳过循环体内余下的语句,重新判断条件以决定是否需要执行下一次循环)
[root@server0 opt]# vim 7.sh ##此脚本是为了演示exit的效果
#!/bin/bash
for i in a b c
do
echo 123
exit
echo 456
done
echo xyz
[root@server0 opt]# bash 7.sh
123
--------------------------------------------------------------------------------
[root@server0 opt]# vim 7.sh ##此脚本是为了演示break的效果
#!/bin/bash
for i in a b c
do
echo 123
break
echo 456
done
echo xyz
[root@server0 opt]# bash 7.sh
123
xyz
--------------------------------------------------------------------------------
[root@server0 opt]# vim 7.sh ##此脚本是为了演示continue的效果
#!/bin/bash
for i in a b c
do
echo 123
continue
echo 456
done
echo xyz
[root@server0 opt]# bash 7.sh
123
123
123
xyz
编写脚本,可以帮助用户计算整数的求和
[root@server0 opt]# vim 6.sh
#!/bin/bash
#这是一个整数求和的测试脚本
x=0
while :
do
read -p "请输入一个数字,0是结束" n
[ $n -eq 0 ] && break
let x+=n
done
echo "总数是$x"
[root@server0 opt]# bash 6.sh
请输入一个数字,0是结束2
请输入一个数字,0是结束2
请输入一个数字,0是结束2
请输入一个数字,0是结束0
总数是6
编写一个从1-20中找出6的倍数的脚本
[root@server0 opt]# vim 8.sh
#!/bin/bash
for i in {1..20}
do
x=$[i%6]
[ $x -ne 0 ] && continue
echo $i
done
[root@server0 opt]# bash 8.sh
6
12
18
字符串截取
字符串截取的用法:
格式: ${变量名:起始位置:长度} ##起始位置从0开始
字串替换的两种用法:
只替换第一个匹配结果:${变量名/old/new}
替换全部匹配结果:${变量名//old/new}
字符串掐头去尾:
从左向右,最短匹配删除:$ {变量名#*关键词} ##掐头
从左向右,最长匹配删除:$ {变量名##*关键词}
从右向左,最短匹配删除:$ {变量名%关键词*} ##去尾
从右向左,最长匹配删除:${变量名%%关键词*}
使用${}方式截取字符串时,起始位置是从0开始的。
[root@server0 opt]# a=abc
[root@server0 opt]# echo $a
abc
[root@server0 opt]# echo ${a:1:1} ##截取b
b
[root@server0 opt]# a=abcdefg ##截取def
[root@server0 opt]# echo ${a:3:3}
def
[root@server0 opt]# a=10
[root@server0 opt]# echo ${a::2}RMB
10RMB
[root@server0 opt]# x=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
[root@server0 opt]# echo ${x:10:1}
k
使用${变量名/old/new}字符串的替换
[root@server0 opt]# a=abc
[root@server0 opt]# echo ${a/b/8}
a8c
[root@server0 opt]# a=aabbcc
[root@server0 opt]# echo ${a/b/8}
aa8bcc
[root@server0 opt]# echo ${a//b/8}
aa88cc
使用${变量名#}字符串的删除 从左往右删
[root@server0 opt]# u=`head -1 /etc/passwd`
[root@server0 opt]# echo $a
root:x:0:0:root:/root:/bin/bash
[root@server0 opt]# echo ${u#root} ##从左往右删除第1个root
:x:0:0:root:/root:/bin/bash
[root@server0 opt]# echo ${u#root:} ##从左往右删除到root:
x:0:0:root:/root:/bin/bash
[root@server0 opt]# echo ${u#*:} ##从左往右删除到第1个: 效果同上
x:0:0:root:/root:/bin/bash
[root@server0 opt]# echo ${u#*x} ##从左往右删除到第1个x
:0:0:root:/root:/bin/bash
[root@server0 opt]# echo ${u#*t} ##从左往右删除到第1个t
x:0:0:root:/root:/bin/bash
[root@server0 opt]# echo ${u##*root} ##从左往右删除到最后一个root
:/bin/bash
[root@server0 opt]# echo ${u##*/} ##从左往右删除到最后一个/
bash
[root@server0 opt]# echo ${u#*:root} ##从左往右删除到第1个:root
:/root:/bin/bash
使用${变量名%}字符串的删除 从右往左删
[root@server0 opt]# u=`head -1 /etc/passwd`
[root@server0 opt]# echo $a
root:x:0:0:root:/root:/bin/bash
[root@server0 opt]# echo ${a%bash} ##从右往左删除第一个bash
root:x:0:0:root:/root:/bin/
[root@server0 opt]# echo ${a%/bash} ##从右往左删除第一个/bash
root:x:0:0:root:/root:/bin
[root@server0 opt]# echo ${a%/*} ##从右往左删除第一个/
root:x:0:0:root:/root:/bin
[root@server0 opt]# echo ${a%%/*} ##从右往左删除最后一个/
root:x:0:0:root:
[root@server0 opt]# echo ${a%%:*} ##从右往左删除最后一个:
root
利用字串符截取编写一个随机密码的脚本
[root@server0 opt]# vim 2.sh
#!/bin/bash
#这是一个8位随机数的测试脚本
x=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ##定义变量
for i in {1..8} ##在1-8数值之间循环
do
n=$[RANDOM%62] ##1-62位随机数
p=${x:n:1} ##截取1位随机数
pass=$pass$p ##每次循环截取的1位随机数存放在pass
done
echo $pass
pass= ##注意事项: 用source去执行这个脚本的话要加这一行及空行.否则截取的就不是8位随机数
[root@server0 opt]# bash 2.sh
efz5O369
[root@server0 opt]# . 2.sh
STziKLQL
利用字串符删除功能编写一个修改后缀名的脚本
[root@server0 opt]# vim 3.sh
#!/bin/bash
#这是一个修改扩展名的测试脚本
for i in `ls *.txt` ##找出所有.txt文件,逐一交给for循环
do
n=${i%.*} ##去尾, 得到不带扩展名的文件名
mv $i $n.doc ##与.doc重新组合
done
[root@server0 opt]# ls
1.sh 2.txt 4.txt 6.txt 8.sh 9.txt nginx-1.12.2
1.txt 3.sh 5.txt 7.sh 8.txt lnmp_soft rh
2.sh 3.txt 6.sh 7.txt 9.sh lnmp_soft.tar.gz
[root@server0 opt]# bash 3.sh
[root@server0 opt]# ls
1.doc 2.sh 4.doc 6.sh 8.doc 9.sh nginx-1.12.2
1.sh 3.doc 5.doc 7.doc 8.sh lnmp_soft rh
2.doc 3.sh 6.doc 7.sh 9.doc lnmp_soft.tar.gz
--------------------------------------------------------------------------------
改良版
[root@server0 opt]# vim 4.sh
#!/bin/bash
#这是一个修改扩展名的测试脚本
read -p "请输入你要修改的文件的后缀名:" a
read -p "请输入新的文件扩名名:" b
for i in `ls *.$a`
do
n=${i%.*}
mv $i $n.$b
done
[root@server0 opt]# ls
1.doc 2.sh 4.doc 6.doc 7.sh 9.doc lnmp_soft.tar.gz
1.sh 3.doc 4.sh 6.sh 8.doc 9.sh nginx-1.12.2
2.doc 3.sh 5.doc 7.doc 8.sh lnmp_soft rh
[root@server0 opt]# bash 4.sh
请输入你要修改的文件的后缀名:doc
请输入新的文件扩名名:txt
[root@server0 opt]# ls
1.sh 2.txt 4.sh 6.sh 7.txt 9.sh lnmp_soft.tar.gz
1.txt 3.sh 4.txt 6.txt 8.sh 9.txt nginx-1.12.2
2.sh 3.txt 5.txt 7.sh 8.txt lnmp_soft rh
字符串初值的处理
- 字符串的初值(备用值),变量非空时不使用
格式
- ${变量名:-备用值}
[root@proxy ~]# cat /root/test.sh
#!/bin/bash
read -p "请输入用户名:" user
[ -z $user ] && exit //如果无用户名,则脚本退出
read -p "请输入密码:" pass
pass=${pass:-123456} //如果用户没有输入密码,则默认密码为123456
useradd $user
echo "$pass" | passwd --stdin $user
利用for循环写一个九九乘法表
[root@proxy2 opt]# bash test08.sh
#!/bin/bash
for i in {1..9}
do
for o in `seq $i`
do
echo -n "${i}X$o=$[i*o] "
done
echo
done
[root@proxy2 opt]# bash test08.sh
1X1=1
2X1=2 2X2=4
3X1=3 3X2=6 3X3=9
4X1=4 4X2=8 4X3=12 4X4=16
5X1=5 5X2=10 5X3=15 5X4=20 5X5=25
6X1=6 6X2=12 6X3=18 6X4=24 6X5=30 6X6=36
7X1=7 7X2=14 7X3=21 7X4=28 7X5=35 7X6=42 7X7=49
8X1=8 8X2=16 8X3=24 8X4=32 8X5=40 8X6=48 8X7=56 8X8=64
9X1=9 9X2=18 9X3=27 9X4=36 9X5=45 9X6=54 9X7=63 9X8=72 9X9=81