1.for语句
第一种:
for i in {1..10}
do
echo $i
done
第二种:
a=1
b=10
for i in `seq $a $b`
do
echo $i
done
第三种:
a=1
b=10
for i in `seq $a 2 $b` ##步长为2
do
echo $i
done
第四种:
for i in tom jian sam
do
echo $i
done
第五种:
for ((i=1;i<10;i++))
do
echo $i
done
第六种:
for ((i=1;i<10;i+=2))
do
echo $i
done
小测试:
自动测试172.25.254.网段的1~10主机网络是否通畅,要求:显示通畅的。
2.while语句
while 条件
do
done
while true 条件成立就一直执行
适用于监控脚本
while true
do
read -p "Please input a word:" WORD
echo $WORD
done
untill false
until false
do
read -p "Please input a word:" WORD
echo $WORD
done
小测试:
监控系统负载,要求:每个三秒显示在终端上。
while true
do
clear
echo `uptime`
sleep 3
done
3.if语句
结构为:
if
then
elif
then
。。。
else
fi
if语句示例:
小测试:
创建脚本create_user.sh,要求:脚本执行时创建出脚本后跟的文件中写的用户,并修改用户密码为密码文件中的密码。
userfile文件中:
user1
user2
user3
passwdfile文件中:
123
456
789
vim create_user.sh
if [ -z $1 ]
then
echo "Error:userfile is not input!"
elif [ ! -e $1 ]
then
echo "Error:$1 is not exist!"
elif [ -z $2 ]
then
echo "Error:passwdfile is not input!"
elif [ ! -e $2 ]
then
echo "Error:$2 is not exist"
else
Num=`awk 'BEGIN{N=0}{N++}END{print N}' $1`
for i in `seq 1 $Num`
do
USERNAME=`sed -n ${i}p $1`
PASSWD=`sed -n ${i}p $2`
getent passwd $USERNAME &> /dev/null
if [ "$?" = "0" ]
then
echo "$USERNAME is exist"
else
useradd $USERNAME
echo $PASSWD | passwd --stdin $USERNAME &> /dev/null
echo "$USERNAME is created successfully!"
fi
done
fi
4.case语句
case语句结构
case
word1 )
action1
;;
word2)
action2
;;
…
*)
action_last
esac
case语句示例:
case $1 in
linux|LINUX|Linux)
echo westos
;;
westos|WESTOS|Westos)
echo linux
;;
lee|LEE|Lee)
echo zhang
;;
*)
echo error
esac
与if语句相比较case有优势:
5.expect
expect 是自动应答命令用于交互式命令的自动执行,借助expect处理交互的命令,可以将交互过程如:ssh登录,ftp登录等写载一个脚本上,使之自动化完成。尤其适用于需要对多台服务器执行相同操作的环境中,可以大大提高系统管理人员的工作效率。
- spawn 是 expect 中的监控程序,其运行后会监控命令提出的交互问题
- send,发送问题答案给交互命令
- “\r”,表示回车
- exp_continue,表示当问题不存在时继续回答下面的问题
- expect eof ,表示问题回答完毕退出 expect 环境
- interact,表示问题回答完毕留在交互界面
- set NAME [ lindex $argv n ],定义变量
- set timeout -1 设置超时方式为永远等待
- set timeout 30 设置超时时间为30秒
- [lindex $argv 0] 获取expect脚本的第1个参数
- [lindex $argv 1] 获取expect脚本的第2个参数
不用expect写个脚本 ask.sh:
由上可以发现在不用expect的情况下比较繁琐,需要一个个输入。
我们也可以将答案事先写好经过重定向输入到脚本里。
但如果注释掉原程序里一段,则输出结果会发生错乱。
为解决这种问题,我们引入expect。
- 首先要安装expect
yum install expect
写到一起
#!/usr/bin/expect
set NAME [ lindex $argv 0 ]
set AGE [ lindex $argv 1 ]
set OBJ [ lindex $argv 2 ]
set FEEL [ lindex $argv 3]
spawn sh /mnt/ask.sh
expect {
"name" { send "$NAME\r" ; exp_continue }
"old" { send "$AGE\r" ; exp_continue }
"object" { send "$OBJ\r" ; exp_continue }
"happy" { send "$FEEL\r" }
}
expect of
小实验1:
知道某一主机的密码,要求用ssh连接这台主机,要求:利用expect完成。
小实验2:
编写脚本显示172.25.254网段的1-10台主机里开着的主机名,要求:利用expect完成。
提示:expect+for循环
vim hostname.sh
#!/bin/bash
Auto_SSH() 写一个函数
{
/usr/bin/expect <<-EOF
spawn ssh root@$1 hostname ##对齐写,将这些东西输入定向到expect的环境中运行
expect {
"yes/no" { send "yes\r" ; exp_continue }
"password" { send "redhat\r" } ##前面的是提取的关键字,后面发送的是答案
}
expect eof
EOF
}
for IP in {1..10}
do
ping -c1 -w1 172.25.254.$IP &> /dev/null
if [ "$?" = "0" ]
then
Auto_SSH 172.25.254.$IP | tail -n 1
fi
done
6.脚本中的语句控制器
exit n 脚本退出,退出值为 n
break 退出当前循环
continue 提前结束循环内部的命令,但不终止循环
原程序:
运行结果:
exit 0
运行结果:
break
运行结果:
continue
运行结果: