Shell脚本(四)-脚本中的常用语句及控制器

脚本中的常用语句

for语句(循环)

for语句会将语句中的值依次赋予语句中的变量,每一次赋值执行一次
格式:
for 变量 in 值
do
    执行内容
done
或
for ((变量初始值;循环控制条件;变量修正值))
do
    执行内容
done

例:
[root@desktop80 ~]# vim for.sh 
for a in {1..5}
do
        echo a=$a
done
for ((b=1;b<=5;b++))
do
        echo b=$b
done
[root@desktop80 ~]# sh for.sh 
a=1
a=2
a=3
a=4
a=5
b=1
b=2
b=3
b=4
b=5

while语句

while命令当条件满足时,进入循环
格式:
while 条件
do
    执行内容
done

例:检测/目录使用超过30%,打印提示到当前shell
[root@desktop80 sh]# vim disk.sh
#!/bin/bash
DISK_USE=`df | awk '/\/$/{print $5}' | awk -F "%" '{print $1}'`

while [ "$DISK_USE" -ge "30" ] ; do
        echo "Your / will full !!" > `tty`
        sleep 10
done

[root@desktop80 sh]# sh disk.sh 
Your / will full !!
Your / will full !!
^C

if语句

if语句判断多个条件,不同条件成立,执行相应的内容
格式:
if 条件1           ##如果
then 执行内容1     ##则执行
elif 条件2         ##又如果
then 执行内容2     ##则执行
。。。             ##可重复加多个条件
else              ##当条件都不满足时,执行
fi 

例:
#!/bin/bash
read -p "Do you like cats or dogs?" LIKE
if [ "$LIKE" = cat ]
then
        echo dog?
elif [ "$LIKE" = dog ]
then
        echo cat?
else
        echo what?
fi

[root@desktop80 sh]# sh if.sh 
Do you like cats or dogs?cat
dog?
[root@desktop80 sh]# sh if.sh 
Do you like cats or dogs?dog
cat?
[root@desktop80 sh]# sh if.sh 
Do you like cats or dogs?ls
what?

case语句

case语句同if语句都是判断多条件,差别在于if语句为逐条判断,case语句为同时判断,效率较高
格式:
case 判断条件 in
    条件1)
    执行内容1
    ;;
    条件2)
    执行内容2
    ;;
    。。。
    *)
    默认执行内容        ##当使用前面的各种模式均无法匹配该变量时,将执行“*)”后
    ;;
esac

例:
[root@desktop80 sh]# vim case.sh
case $1 in
        cat)
        echo dog
        ;;
        dog)
        echo cat
        ;;
        *)
        echo "Errot:input cat or dog after script !!"
esac

[root@desktop80 sh]# sh case.sh cat
dog
[root@desktop80 sh]# sh case.sh dog
cat
[root@desktop80 sh]# sh case.sh 
Errot:input cat or dog after script !!

expect

通过上面的语句我们可以实现简单的循环、判断等功能,但对于需要交互的场景,就不许通过人工来干预。expect则是可以实现交互的程序
spawn    expect中的监控程序,其运行后会监控命令提出的交互问题
send    发送问题答案给交互命令
"\r"    回车
exp_continue    当前问题如果不存在时,继续回答下面的问题
expect eof      问题回答完毕退出expect环境
interact        问题回答完毕留在交互界面
set NAME [ lindex $argv n ]    定义变量

###安装expect服务
[root@desktop80 sh]# yum install expect -y
[root@desktop80 sh]# type expect
expect is /usr/bin/expect

例:
[root@desktop80 sh]# vim ssh.exp
#!/usr/bin/expect
set ip [ lindex $argv 0 ]
set password [ lindex $argv 1 ]
set timeout 5
spawn ssh root@$ip
expect {
        "yes/no" { send "yes\r";exp_continue }
        "password" { send "$password\r" }
}
interact

[root@desktop80 sh]# ./ssh.exp 172.25.80.100 redhat
spawn ssh [email protected]
[email protected]'s password: 
Last login: Tue Jun 26 20:59:00 2018 from 172.25.80.250
[root@server80 ~]# exit

脚本中的语句控制器

exit n:脚本退出,退出值为n
break:退出当前循环,但不退出脚本
continue:提前结束循环内部的命令,但不终止当前循环

脚本应用示例

用户创建脚本
执行users_create.sh userlist passlist
建立userlist列表中的用户
设定列表中用户的密码为passlist列表中的密码
脚本后输入文件个数不足时报错
两个文件行数不一致时报错
文件不存在时报错
用户存在时报错

[root@desktop80 sh]# vim users_create.sh
#!/bin/bash
if [ $# -lt 2 ]
then
        echo "Please input userlist and passlist after the script !!"
        exit 1
elif [ ! -e $1 ]
then
        echo "ERROR: $1 is not exist!!"
        exit 1
elif [ ! -e $2 ]
then
        echo "ERROR: $2 is not exist!!"
        exit 1
elif [ `cat $1 | wc -l` -ne `cat $2 | wc -l` ]
then
        echo "The number of file lines must be the same !!"
        exit 1
else
        Max_Line=`cat $1 | wc -l`
        for Line_num in `seq 1 $Max_Line`
        do
                Username=`sed -n "${Line_num}p" $1`
                Password=`sed -n "${Line_num}p" $2`
                useradd $Username && {
                echo $Username Created successfully     
                echo $Password | passwd --stdin $Username
                }
        done
fi

测试:
[root@desktop80 sh]# sh users_create.sh                     ##运行脚本
Please input userlist and passlist after the script !!      ##错误提示
[root@desktop80 sh]# cat >> userlist << EOF                 ##创建用户列表文件
> user1
> user2
> user3
> user4
> EOF
[root@desktop80 sh]# sh users_create.sh userlist passlist    ##执行脚本
ERROR: passlist is not exist!!                               ##错误提示

[root@desktop80 sh]# cat >> passlist << EOF                  ##创建密码文件,与用户文件行数不对应
> pass1
> pass2
> pass3
> EOF
[root@desktop80 sh]# sh users_create.sh userlist passlist    ##执行脚本
The number of file lines must be the same !!                 ##错误提示

[root@desktop80 sh]# echo pass4 >> passlist                  ##修改passlist文件
[root@desktop80 sh]# sh users_create.sh userlist passlist    ##执行脚本
user1 Created successfully
Changing password for user user1.
passwd: all authentication tokens updated successfully.
user2 Created successfully
Changing password for user user2.
passwd: all authentication tokens updated successfully.
user3 Created successfully
Changing password for user user3.
passwd: all authentication tokens updated successfully.
user4 Created successfully
Changing password for user user4.
passwd: all authentication tokens updated successfully.

[root@desktop80 sh]# sh users_create.sh userlist passlist    ##再次执行,提示用户已存在
useradd: user 'user1' already exists
useradd: user 'user2' already exists
useradd: user 'user3' already exists
useradd: user 'user4' already exists

########################################邪恶的分隔线########################################

数据库备份
执行db_dump.sh westos(数据库密码)
脚本执行后会备份数据库中的所有库到/mnt/mysqldump目录中
备份文件名称为"库名称.sql" 当次文件存在时报错并询问动作
输入"S"跳过备份,输入"B"备份"库名称.sql"文件为"库名称_backup_当前日期.sql",输入"O"时,覆盖源文件

[root@desktop80 sh]# vim db_dump.sh
ACTION_CMD(){
        read -p "[S]kip [B]ackup [O]verwrite
        Please input action: " ACTION
        ACTION=`echo $ACTION | tr 'a-z' 'A-Z'`
        case $ACTION in
                S)
                continue
                ;;
                B)
                mv /mnt/mysqldump/${2}.sql /mnt/mysqldump/${2}_backup_`date +%y-%m-%d`.sql
                ;;
                O)
                mysqldump -uroot -p$1 $2 > /mnt/mysqldump/${2}.sql
                ;;
                exit)
                echo bye[root@desktop80 sh]# vim test.sh 


                exit 0[root@desktop80 sh]# vim test.sh 


                ;;
                *)
                echo "ERROR: please input [S] [B] [O] "
                ACTION_CMD
        }

TABASE_MESSAGE=`mysql -uroot -EN -e "show databases;" | grep -v -E "^\*|schema$"`

for DATABASE_NAME in $DATABASE_MESSAGE
do
        [ -e "/mnt/mysqldump/${DATABASE_NAME}.sql" ] && {
        ACTION_CMD $1 $DATABASE_NAME 
        } || {
        mysqldump -uroot -p$2 $DATABASE_NAME > /mnt/mysqldump/$DATABASE_NAME.sql
        }
done

########################################邪恶的分隔线########################################

自动部署服务
执行lamp.sh,自动部署apache服务,并设定监听端口为8080

[root@desktop80 sh]# vim lamp.sh 
#!/bin/bash
yum repolist
yum install httpd -y
sed -i "/^Listen/cListen 8080" /etc/httpd/conf/httpd.conf
systemctl stop httpd
systemctl start httpd
systemctl enable httpd


猜你喜欢

转载自blog.csdn.net/xin1889/article/details/80846903