脚本中的常用语句
for语句(循环)
for语句会将语句中的值依次赋予语句中的变量,每一次赋值执行一次
格式:
for 变量 in 值
do
执行内容
done
或
for ((变量初始值;循环控制条件;变量修正值))
do
执行内容
done
例:
[[email protected] ~]# vim for.sh
for a in {1..5}
do
echo a=$a
done
for ((b=1;b<=5;b++))
do
echo b=$b
done
[[email protected] ~]# 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
[[email protected] 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
[[email protected] 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
[[email protected] sh]# sh if.sh
Do you like cats or dogs?cat
dog?
[[email protected] sh]# sh if.sh
Do you like cats or dogs?dog
cat?
[[email protected] sh]# sh if.sh
Do you like cats or dogs?ls
what?
case语句
case语句同if语句都是判断多条件,差别在于if语句为逐条判断,case语句为同时判断,效率较高
格式:
case 判断条件 in
条件1)
执行内容1
;;
条件2)
执行内容2
;;
。。。
*)
默认执行内容 ##当使用前面的各种模式均无法匹配该变量时,将执行“*)”后
;;
esac
例:
[[email protected] sh]# vim case.sh
case $1 in
cat)
echo dog
;;
dog)
echo cat
;;
*)
echo "Errot:input cat or dog after script !!"
esac
[[email protected] sh]# sh case.sh cat
dog
[[email protected] sh]# sh case.sh dog
cat
[[email protected] 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服务
[[email protected] sh]# yum install expect -y
[[email protected] sh]# type expect
expect is /usr/bin/expect
例:
[[email protected] 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
[[email protected] 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
[[email protected] ~]# exit
脚本中的语句控制器
exit n:脚本退出,退出值为n
break:退出当前循环,但不退出脚本
continue:提前结束循环内部的命令,但不终止当前循环
脚本应用示例
用户创建脚本
执行users_create.sh userlist passlist
建立userlist列表中的用户
设定列表中用户的密码为passlist列表中的密码
脚本后输入文件个数不足时报错
两个文件行数不一致时报错
文件不存在时报错
用户存在时报错
[[email protected] 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
测试:
[[email protected] sh]# sh users_create.sh ##运行脚本
Please input userlist and passlist after the script !! ##错误提示
[[email protected] sh]# cat >> userlist << EOF ##创建用户列表文件
> user1
> user2
> user3
> user4
> EOF
[[email protected] sh]# sh users_create.sh userlist passlist ##执行脚本
ERROR: passlist is not exist!! ##错误提示
[[email protected] sh]# cat >> passlist << EOF ##创建密码文件,与用户文件行数不对应
> pass1
> pass2
> pass3
> EOF
[[email protected] sh]# sh users_create.sh userlist passlist ##执行脚本
The number of file lines must be the same !! ##错误提示
[[email protected] sh]# echo pass4 >> passlist ##修改passlist文件
[[email protected] 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.
[[email protected] 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"时,覆盖源文件
[[email protected] 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[[email protected] sh]# vim test.sh
exit 0[[email protected] 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
[[email protected] 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