在shell环境中,将一些需要重复使用的操作,定义为公共的语句块,即可称为函数(给一堆命令取一个别名)
函数可以使脚本中的代码更加简洁,增强易读性,提高脚本的执行效率
#函数定义格式1
function 函数名 {
执行的命令1
执行的命令2
...省略更多命令
}
#函数定义格式2
函数名() {
执行的命令1
执行的命令2
...省略更多命令
}
#定义函数
#!/bin/bash
net() {
ifconfig ens32 | grep "RX packets"
ifconfig ens32 | grep "TX packets"
}
while :
do
clear
net #调用函数
sleep 1
done
#定义Nginx status页面
ngx_status="http://127.0.0.1/status"
#判断status页面是否存活
ngx_status_code() {
http_code=`curl -o /dev/null -s -w %{http_code} ${ngx_status}`
if [ ${http_code} == "200" ];then
return 1
else
echo "Nginx status is not running."
fi
}
#获取当前活动的客户端连接数
active() {
ngx_status_code || curl -s ${ngx_status} | grep "Active" | awk '{print $NF}'
}
#获取接收客户端连接的总数量
accepts() {
ngx_status_code || curl -s ${ngx_status} | awk NR==3 | awk '{print $1}'
}
#获取已处理的连接总数量
handled() {
ngx_status_code || curl -s ${ngx_status} | awk NR==3 | awk '{print $2}'
}
#获取客户端请求总数量
requests() {
ngx_status_code || curl -s ${ngx_status} | awk NR==3 | awk '{print $3}'
}
#获取正在读取请求标头的当前连接数量
reading() {
ngx_status_code || curl -s ${ngx_status} | grep "Reading" | awk '{print $2}'
}
#获取正在将响应写回到客户端的当前连接数量
writing() {
ngx_status_code || curl -s ${ngx_status} | grep "Writing" | awk '{print $2}'
}
#获取当前正在等待响应的客户端连接数量
waiting() {
ngx_status_code || curl -s ${ngx_status} | grep "Waiting" | awk '{print $2}'
}
#使用位置变量控制脚本输出
case $1 in
active)
active;;
accepts)
accepts;;
handled)
handled;;
requests)
requests;;
reading)
reading;;
writing)
writing;;
waiting)
waiting;;
*)
echo "Unknown options"
esac
#fork炸弹
vim fork.sh
#!/bin/bash
.() {
.|. &
}
.
chmod u+x fork.sh
./fork.sh
脚本中断及退出
break #结束整个循环
continue #结束本次循环,进入下一次循环
exit #退出脚本
#例子
#!/bin/bash
for i in {1..5}
do
echo $i
done
echo Over
#跳过第三次循环,进入下一次循环
#结束第三次循环,进入下一次循环
#!/bin/bash
for i in {1..5}
do
[ $i -eq 3 ] && continue
echo $i
done
echo Over
./for1.sh
1
2
4
5
Over
#结束整个循环
#!/bin/bash
for i in {1..5}
do
[ $i -eq 3 ] && break
echo $i
done
echo Over
./for1.sh
1
2
Over
#直接退出脚本
vim for1.sh
#!/bin/bash
for i in {1..5}
do
[ $i -eq 3 ] && exit
echo $i
done
echo Over
./for1.sh
1
2
字符串截取
在使用shell脚本完成各种运维任务时,一旦涉及到判断、条件测试等相关操作时往往需要对相关的命令输出进行过滤,提取出符合要求的字符串
字符串截取的常用方法:${变量名:起始位置:长度}
${}截取字符串时,起始位置是从0开始的
phone=13812345678
echo $phone
13812345678
#统计变量的个数
echo ${#phone}
11
#截取变量的前三位,在截取时包含数字本身
echo ${phone:0:3}
138
#截取后四位
echo ${phone:7:4}
5678
#截取中间四位
echo ${phone:3:4}
1234
#截取一个随机的8位密码
pass=qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789
for i in {1..8}
do
num=$[RANDOM%62]
num1=${pass:num:1}
num2=$num2$num1
done
echo $num2
字符串替换
只替换第一个匹配的结果:${变量名/xx/yy}
替换全部匹配的结果:${变量名//xx/yy}
#只替换匹配到的第一个字符
echo $phone
13812345678
#将匹配到的第一个3替换成4
echo ${phone/3/4}
14812345678
#将匹配到的所有3替换成4
echo ${phone//3/4}
14812445678
字符串掐头去尾
从左向右,最短匹配删除:${变量名#*关键词}
从左向右,最长匹配删除:${变量名##*关键词}
从右向左,最短匹配删除:${变量名%关键词*}
从右向左,最长匹配删除:${变量名%%关键词*}
#定义素材
x=`head -1 /etc/passwd`
[root@localhost yunwei]# echo $x
root:x:0:0:root:/root:/bin/bash
#从左到右最短匹配
echo ${x#root}
#从左到右最短匹配,不加*只匹配最左侧的字串
echo ${x#0}
#从左到右最短匹配,加*匹配遇到的第一个字串
echo ${x#*0}
#从左到右最长匹配
echo ${x##0}
root:x:0:0:root:/root:/bin/bash
#从左到右最长匹配
echo ${x##*0}
:root:/root:/bin/bash
#从右到做最短匹配
echo ${x%/bash}
root:x:0:0:root:/root:/bin
#从右到做最短匹配
echo ${x%root*}
root:x:0:0:root:/
#从右向左最长匹配
echo ${x%%root*}
#从右向左最短匹配
echo ${x%0*}
root:x:0:
#从右向左最长匹配
echo ${x%%0*}
root:x:
#把文件以.doc结尾的扩展名,全部改为.txt
touch {1..100}.doc
#字符串去尾方式批量修改文件扩展名
vim file.sh
#!/bin/bash
for i in `ls *.doc`
do
mv $i ${i%doc}txt
done
#字符串替换方式批修改文件扩展名
vim file.sh
#!/bin/bash
for i in `ls *.txt`
do
mv $i ${i/txt/doc}
done
shell数组
#定义数组方式一:数组名=(值1 值2 值3 .. .. 值n)
phone=(13112345678 13212345678 13412345678 13512345678 13612345678)
#按照下标取值,下标从0起使,0就是数组内的第一个值
echo ${x[0]}
echo ${x[0]}
echo ${x[1]}
echo ${x[2]}
echo ${x[3]}
echo ${x[4]}
#获取数组内所有值
echo ${x[@]}
echo ${x[*]}
#向数组内赋值:数组名[下标]=值
phone[5]=13812345678
echo ${b[*]}
#通过数组下载软件包
vim yum.sh
#!/bin/bash
x=(vsftpd httpd gcc openssl-devel pcre-devel)
for i in ${x[@]}
do
yum -y install $i
done
正则表达式
正则表达式使用一串符号描述有共同属性的数据
#匹配以什么什么开头的行
grep "^root" /etc/passwd
grep "^#" /etc/fstab
#匹配以什么什么结尾的行
grep "bash$" /etc/passwd
#排除
grep -v "^#" /etc/fstab
grep -v "^#" /etc/fstab | grep -v "^$"
#集合,匹配集合中的任意单个字符
grep "ro[abcotabcd]" /etc/passwd
#集合,对集合中的任意单个字符取反
grep "ro[^abcotabcd]" /etc/passwd
#匹配任意单个字符
grep "roo." /etc/passwd
grep ".oot" /etc/passwd
grep "w.*" /etc/passwd
#或者
egrep "root|bash" /etc/passwd
netstat -ntlp | egrep "22|80"