一、read 的简单应用:
-p 提示用户输入内容
-n 判断输入的字符个数
-s 隐藏用户的输入内容,一般适用于输入密码的时候
-t 等待一定的时间后没有输入信息,自动结束
-d 输入分界
-a 把输入信息读入到数组里
-r 允许输入包含" \ "的内容
(1)read -p
(2)read -n
(3)read -s
(4)read -t
(5)read -a
(6)read -r
简单脚本验证:
#!/bin/bash
read -p "请输入您的账号:" name
if [ $name == 'bob' ];then
read -rsp "请输入您的密码:" passwd
if [ $passwd == '123\321' ];then
echo -e "\n欢迎登录" #-e允许输入换行符,与"\n"连用
else
echo -e "\n密码错误"
fi
else
echo "不存在的账号"
fi
二、简单的监控脚本
#!/bin/bash
for i in `cat port.txt` #port.txt内容为对应的服务端口
do
port=`ss -ntulp|grep $i | awk '{print $5}' | awk -F ":" '{print $2}'`
if [ "$port" == "$i" ];then
echo "httpd is up"
else
echo "httpd is down"
systemctl start httpd
fi
done
三、shell中的数值运算
1、整数运算工具expr、$[ ]、let。
a、 expr
:乘法操作符需添加 \ 转义,除法仅保留整除结果
b、$[]
:乘法操作符无需转义;运算符两侧可以无空格;引用变量可省略$符号;计算结果替换表达式本身,可结合echo命令输出。
c、let
命令
expr或$[ ]方式只进行运算,并不会改变变量的值;而let命令可以直接对变量值做运算再保存新的值。因此变量x=100,再执行let运算后的值会变更;let运算操作并不显示结果,但是可以结合echo命令来查看。
#!/bin/bash
let y=x+1;echo $y
let x++;echo $x # x++(x=x+1)
let x--;echo $x # x--(x=x-1)
let x+=2;echo $x # x+=2(x=x+2)
let x-=2;echo $x # x-=2(x=x-2)
let x*=2;echo $x # x*=2(x=x*2)
let x/=2;echo $x # x/=2(x=x/2)
let x%=2;echo $x # x%=2(x=x%2)
d、小数运算工具使用 bc
四、特殊判断字符的使用
1、字符串比较
"==" 比较两个字符串是否相同
"!=" 比较两个字符串是否不相同
"-z" 检查变量的值是否未设置
#!/bin/bash
x=$1
if [ "$1" == "abcd" ];then
echo "相同"
elif [ -z "$1" ];then
echo "未赋值"
elif [ "$1" != "abcd" ];then
echo "不同"
else
echo "ooooo"
fi
2、逻辑或、逻辑与
A && B (仅当A命令执行成功,才执行B命令,给定条件必须都成立,整个测试结果才为真)
A || B (仅当A命令执行失败,才执行B命令,只要其中一个条件成立,则整个测试结果为真)
A ; B (执行A命令后执行B命令,两者没有逻辑关系)
3、整数值比较(必须是整数,可以调用变量,比较非整数值时会出错)
(1)-eq 比较两个数是否相等
(2)-ne 比较两个数是否不相等
(3)-gt 比较前面的整数是否大于后面的整数
(4)-ge 比较前面的整数是否大于或等于后面的整数
(5)-lt 比较前面的整数是否小于后面的整数
(6)-le 比较前面的整数是否小于或等于后面的整数
(7)提取当前登录的用户数
#!/bin/bash
x=50
echo $x
[ "$x" -eq "50" ] && echo "等于50" || echo "不等于50"
[ "$x" -ne "40" ] && echo "不等于40" || echo "等于40"
[ "$x" -gt "40" ] && echo "大于40" || echo "不大于40"
[ "$x" -ge "40" ] && echo "大于或等于40" || echo "小于40"
[ "$x" -lt "60" ] && echo "小于60" || echo "不小于60"
[ "$x" -le "60" ] && echo "小于或等于60" || echo "大于60"
N=`who | wc -l`;echo 当前登录人数为"$N"个
4、识别文件或目录的状态
(1)-e 判断对象是否存在(不管是文件还是目录)
(2)-d 判断对象是否为目录(存在并且是目录)
(3)-f 判断对象是否为文件 (存在并且是文件)
(4)-r 判断对象是否可读 (对root用户无效)
(5)-w 判断对象是否可写 (对root用户无效)
(6)-x 判断对象是否具有可执行权限 (对所有用户均适用)
#!/bin/bash
[ -e "/root/shell/let.sh" ] && echo "存在" || echo "不存在"
[ -e "/root/shell" ] && echo "存在" || echo "不存在"
[ -d "/root/shell" ] && echo "是目录" || echo "不是目录"
[ -d "/root/shell/let.sh" ] && echo "是目录" || echo "不是目录"
[ -f "/root/shell" ] && echo "是文件" || echo "不是文件"
[ -f "/root/shell/let.sh" ] && echo "是文件" || echo "不是文件"
[ -r "/root/shell/let.sh" ] && echo "可读" || echo "不可读"
[ -w "/root/shell/let.sh" ] && echo "可写" || echo "不可写"
[ -x "/root/shell/let.sh" ] && echo "可执行" || echo "不可执行"
5、检测服务器是否可ping通
#!/bin/bash
for ip in `cat ip.txt`
do
ping -c 3 -i 0.2 -w 1 $ip &> /dev/null
if [ $? -eq 0 ];then # $? 判断前一条命令的执行状态,返回为0则执行成功,否则执行失败。
echo "host $ip is up" >> ping.log
else
echo "host $ip is down" >> ping.log
fi
done
五、while循环格式
while循环属于条件式的执行流程,会反复判断指定的测试条件,只要条件成立,则执行固定的一组操作,直到条件变化为不成立为止,所以while循环的条件一般通过变量来进行控制,在循环体内对变量值做相应的改变,以便在适当的时候退出循环,避免造成死循环。
while循环语法结构如下:
while 判断条件
do
需要执行的命令序列
done
或者:
while :
do
需要执行的命令序列
done
简单脚本示例:
#!/bin/bash
num=$[RANDOM%100+1]
i=0
while [ $i -lt 5 ]
do
read -p "请输入随机数1-100:" guess
let i++
if [ $guess -eq $num ];then
echo "恭喜你"
echo "你猜了$i次"
exit
elif [ $guess -gt $num ];then
echo "猜大了"
else
echo "猜小了"
fi
done
六、case分支的用法
case分支属于匹配执行的方式,它针对指定的变量预先设置一个可能的取值,判断该变量的实际取值是否与预设的某一个值相匹配,如果匹配上了,就执行相应的一组操作,如果没有任何值能够匹配,就执行预先设置的默认操作。
case分支语法结构如下:
case 变量 in
条件1)
命令序列1;;
条件2)
命令序列2;;
*)
默认命令序列
esac
简单脚本示例:
#!/bin/bash
case $1 in
"abcd")
echo "dcba";;
"dcba")
echo "abcd";;
*)
echo "abcddcba"
esac
七、shell函数的使用
在shell脚本中,将一些需要重复使用的操作,定义为公共的语句块,即可成为函数。通过使用函数,可以使脚本代码更加简洁,增强易读性,提高shell脚本的执行效率,可以使用 “函数名” 的形式调用函数,如果该函数能够处理位置参数,则可以使用 “函数名 参数1 参数2 … …” 的形式调用(注意:函数的定义语句必须出现在调用之前,否则无法执行。)
函数格式1:
function 函数名 {
命令序列
… …
}
函数格式2:
函数名(){
命令序列
… …
}
脚本示例(调用函数的脚本,在执行的过程中效率更高):
#!/bin/bash
date >> 2.log
myping(){
ping -c3 -i0.2 -w1 $1 &> /dev/null
if [ $? -eq 0 ];then
echo "host $1 is up" >> 2.log
else
echo "host $1 is down" >> 2.log
fi
}
for i in {1..254}
do
myping 192.168.84.$i &
done
date >> 2.log
wait #wait命令的作用是等待所有后台进程都结束了才结束脚本
八、字符串处理(截取、替换)
1、字符串的截取和切割
字符串截取的三种方法:
${变量名:起始位置:长度}
expr substr “$变量名” 起始位置 长度
echo $变量名 | cut -b 起始位置-结束位置
字符串替换的两种方法:
${变量名/old/new} 只替换第一个匹配结果
${变量名//old/new} 替换全部匹配结果
字符串掐头去尾:
${变量名#*关键词} #从左向右,最短匹配删除
${变量名##*关键词} #从左向右,最长匹配删除
${变量名%关键词*} #从右向左,最短匹配删除
${变量名%%关键词*} #从右向左,最长匹配删除
字符串初值:
${var:-word} #若变量var已存在且非Null,则返回$var的值;否则返回字符串“word”,原变量var的值不受影响。
2、示例脚本:
生成随机密码:
#!/bin/bash
pass=""
x=1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
for i in {1..6}
do
num=$[RANDOM%62]
n=${x:num:1}
pass=$pass$n
done
echo $pass
设置默认密码:
#!/bin/bash
read -p "请输入您的名称:" name
if [ $name != "bob" ];then
echo "无效用户"
else
read -sp "请输入您的密码:" pass
if [ -z $pass ];then
pass=${pass:-123456}
fi
echo -e "\n您的密码是$pass"
fi