概述
if选择结构
if单分支处理:当“条件成立”时执行命令序列xx,否则,不执行任何操作(只判断为真)
if [条件测试] ; then
命令序列xx
fi
示例:检测/media/cdrom目录,若不存在则创建
#!/bin/bash
MOUNT_DIR="/media/cdrom/"
if [ ! -d $MOUNT_DIR ] ; then
mkdir -p $MOUNT_DIR
fi
示例:每分钟判断当前登陆用户是否超过3人,若超过3人,自动发送邮件给root,报警!
#!/bin/bash
num=$(who |wc -l) #计算登陆用户
if [ $num -gt 3 ];then #判断用户是否大于3,如果大于,则发送邮件
mail -s Warning abc@163.com < /root/mail.txt
mail -s Warning root < /root/mail.txt
fi
1、chmod +x test.sh
2、将脚本放到计划任务内:crontab -e
* * * * * /root/test.sh
示例:如果是管理员,执行所有命令
#!/bin/bash
if [ $USER == root ];then
yum -y install vsftpd
systemctl start vsftpd
systemctl enable vsftpd`
fi
###############################################################################
if 双分支处理:当“条件成立”时执行命令序列xx,否则,执行命令序列yy(非对即错)
if [条件测试] ; then
命令序列xx
else
命令序列yy
fi
示例:检测并判断指定的主机是否可ping通。用户输入IP地址,判断是否能ping通。能则输出ip地址up;不能则输出ip地址down。
为了节省ping测试时间,可以只发送3个测试包(-c 3)、缩短发送测试包的间隔秒数(-i 0.2)、等待反馈的超时秒数(-W 3)。
#!/bin/bash
read -p '请输入您要测试的IP地址:' ip
ping -c 2 -i 0.1 -W 2 $ip &> /dev/null
if [ $? -eq 0 ] ; then
echo "Host $ip is up."
else
echo "Host $ip is down."
fi
# chmod +x pinghost.sh
# ./pinghost.sh 192.168.4.5
示例:判断用户输入的用户名,该用户是否存在,存在则输出用户id基本信息,不存在则创建此用户
#!/bin/bash
read -p '请输入您的用户名:' user
id $user &> /dev/null 或使用useradd $user
if [ $? -eq 0 ];then
echo 用户已经创建
else
echo 用户已存在
id $user
fi
if 多分支处理:当条件1满足时,作xx处理;否则继续检查
条件2,若成立则作yy处理;否则,作zz处理
相当于多层if语句嵌套,针对多个条件分别执行不同的操作
if [条件测试1] ; then
命令序列xx
elif 条件测试2 ; then
命令序列yy
.. ..
else
命令序列zz
fi
脚本的退出状态:取决于退出前最后一条命令的 $? 值,或者“exit 整数值”指定。
示例:猜数字游戏:
#!/bin/bash
num=$[RANDOM%100]
for i in {1..10}
do
read -p "请输入一个范围在「0-99」的数字: " guess
if [ $num -eq $guess ];then
echo "你猜对了,恭喜您!!!"
echo "随机数为:$num; 您猜的数字为:$guess"
echo "恭喜,猜对了,猜了$i次"
exit
elif [ $num -lt $guess ];then
echo "您猜错了,您输入的数字比随机数大,您猜了$i次"
echo "您猜的数字为:$guess"
else
echo "您猜错了,您输入的数字比随机数小,您猜了$i次"
echo "您猜的数字为:$guess"
fi
done
示例:从键盘读取一个论坛积分,判断论坛用户等级
大于等于90 神功绝世
大于等于80,小于90 登峰造极
大于等于70,小于80 炉火纯青
大于等于60,小于70 略有小成
大于60 初学乍练
#!/bin/bash
read -p "请输入积分(0-100):" JF
if [ $JF –ge 90 ] ; then
echo "$JF 分,神功绝世"
elif [ $JF –ge 80 ] ; then
echo "$JF 分,登峰造极"
elif [ $JF –ge 70 ] ; then
echo "$JF 分,炉火纯青"
elif [ $JF –ge 60 ] ; then
echo "$JF 分,略有小成"
else
echo "$JF 分,初学乍练"
fi
# chmod +x gradediv.sh
# ./gradediv.sh
示例:输入一个分数,判断成绩分档:85-100优秀、70-84良好、低于70分不合格
#!/bin/bash
read -p '请输入您的分数(0-100):' FS
if [ $FS -ge 85 ] && [ $FS -le 100 ];then
echo “ $FS分!优秀 ”
elif [ $FS -ge 70 ] && [ $FS -le 84 ];then
echo “ $FS分!合格 ”
else
echo “ $FS分!不合格 ”
fi
示例:当运行/root/foo.sh redhat,输出为fedora;当运行/root/foo.sh fedora,输出为redhat;当没有任何参数或者参数不是 redhat 或者 fedora时,其错误输出产生以下信息: /root/foo.sh redhat|fedora
1)编写脚本代码# vim /root/foo.sh
#!/bin/bash
if [ "$1" == "redhat" ]
then
echo "fedora"
elif [ "$1" == "fedora" ]
then
echo "redhat"
else
echo "/root/foo.sh redhat|fedora" >&2
fi
另一种写法:
if [ $# == 0 ];then
echo '/root/foo.sh redhat |fedora' >&2 #为了对错误输出进行收集,可通过2>file查看
elif [ $1 == redhat ];then
echo fedora
elif [ $1 == fedora ];then
echo redhat
else
echo '/root/foo.sh redhat |fedora' >&2
fi
2)添加x执行权限# chmod +x /root/foo.sh
3) 测试提供正确参数的情况 # /root/foo.sh redhat
测试提供非预期参数的情况# /root/foo.sh ubuntu
测试不提供参数的情况 # /root/foo.sh
###############################################################################
列表式循环——给定一批对象,反复执行类似的操作(如购票者==>售票)
for循环处理
遍历/列表式循环:根据变量的不同取值,重复执行xx处理
列表式for循环结构:
for 变量名 in 值1 值2 值3 .. .. (变量名一般习惯用i)
do
命令序列($变量名)
done
示例:造数1:touch {1..10000}.txt
#!/bin/bash
for i in `seq 10000`
do
touch /tmp/$i.txt
done
示例:造数2:touch {01..10}.txt
#!/bin/bash
for i in {1..10}
do
useradd stu$i
echo 123456 | passwd --stdin stu$i &> /dev/null
echo stu$i创建成功
id test$a
done
示例:编写一个批量添加用户脚本,此脚本要求提供用户名列表文件作为参数,列表测试文件:http://classroom/pub/materials/userlist。如果没有提供参数,此脚本应该给出提示 Usage: /root/batchusers,退出并返回相应值;如果提供一个不存在的文件,此脚本应该给出提示 Input file not found,退出并返回相应值
1)编写脚本代码# vim /root/batchusers
#!/bin/bash
if [ $# -eq 0 ] ; then #判断位置变量为0个
echo ‘Usage: /root/batchusers’ >&2 #将正确信息变成错误信息
exit 1 #退出返回值为1
fi
if [ ! -f $1 ] ; then #文本不存在为真
echo ‘Input file not found’ >&2 #将正确信息变成错误信息
exit 2 #退出返回值为2
fi
for name in $(cat $1) # $1为文件,cat $1可以显示为文本参数,$()传递参数
do
useradd -s /bin/false $name
done
2)添加x执行权限# chmod +x /root/batchusers
3)测试batchusers批量添加用户脚本
下载用户列表测试文件:
# wget http://classroom/pub/materials/userlist -O /root/userlist
# cat /root/userlist //检查下载文件
实现批量添加用户:# /root/batchusers /root/userlist
# id duanwu
测试其他异常处理:
# /root/batchusers //未提供列表文件, Usage: /root/batchusers <userfile> # echo $? //返回1
# /root/batchusers /root/userlist.txt //提供的列表文件找不到,Input file not found
# echo $? //返回2
###############################################################################
作业:
根据输入成绩的分数 输出不同的提示信息
把指定的文件备份到指定的目录下
判断用户从键盘输入的数据是偶数还是奇数?
计算用户输入1-10之间的任意一个数的平方值,不输入数字的时候给出错误提示信息。
###############################################################################
循环结构
在Shell脚本应用中,常见的for循环采用遍历式、列表式的执行流程,通过指定变量从值列表中循环赋值,每次复制后执行固定的一组操作。
for循环的语法(格式1)
for 变量名 in 值列表
do
命令序列
done
示例:批量添加用户帐号(名称没有规律)
素材:/root/users.txt
#!/bin/bash
ULIST=$(cat /root/users.txt)
for UNAME in $ULIST
do
useradd $UNAME 2>/var/err/log
echo "123456" | passwd --stdin $UNAME > /dev/null
done
# chmod +x uaddfor.sh
# ./uaddfor.sh
示例:使用循环ping测试网络中所有主机
#!/bin/bash
net=192.168.4.
for i in `seq 1 254` #反引号 //{1..254}
do
ping -c 3 -i 0.2 -w 0.2 $net$i &>/dev/null
if [ $? -eq 0 ];then
echo "该主机$net$i,ping通"
else
echo "该主机$net$i,无法ping通"
fi
done
C语言风格的for循环(格式2)
通过变量控制,条件成立时循环;步长可控次数
for ((初值;条件;步长控制))
do
命令序列
done
#!/bin/bash
for ((i=1;i<=5;i+=2)) //或for ((i=1;i<=5;i++))
do
echo $i
done
示例:制作9*9乘法表
#!/bin/bash
for ((i=1;i<=9;i++))
do
for ((j=1;j<=$i;j++))
do
echo -n "$i*$j=$((i*j))"
done
echo
done
++++++++++++++++++++++++
字体色:echo -e "