shell的执行流控制
一、for语句
作用:为循环执行动作
for语句结构
for 定义变量
do 使用变量,执行动作
done 结束标志
for语句的基本格式
格式1
#!/bin/bash
for USER in {1..10}
do
echo $USER
done
格式2
#!/bin/bash
for USER in `seq 1 2 10`
do
echo $USER
done
格式3
#!/bin/bash
for USER in hello westos linux
do
echo $USER
done
格式4
#!/bin/bash
for ((USER=0;USER<=10;USER++))
do
echo $USER
done
练习题
要求:创建文件userlist,内容为“user1 user2 user3”;创建文件passlist,文件内容为"123 456 789";编写一个脚本user_create.sh,使用两个文件创建文件userlist中的用户,并修改为passlist文件中对应的密码
方案一
#!/bin/bash
for I in {1..3}
do
USERNAME=$(sed -n ${I}p userlist)
PASSWORD=$(sed -n ${I}p passlist)
id $USERNAME &> /dev/null &&{
echo $USERNAME is exist
}||{
useradd $USERNAME
echo $PASSWORD | passwd --stdin $USERNAME &> /dev/null &&{
echo $USERNAME is created
}
}
done
方案二
#!/bin/bash
for Line_Number in `seq 1 $(sed -n '$=' $1)`
do
USERNAME=$(sed -n ${Line_Number}p $1)
PASSWORD=$(sed -n ${Line_Number}p $2)
id $USERNAME &> /dev/null &&{
echo $USERNAME is exist
userdel -r $USERNAME
}||{
useradd $USERNAME
echo $PASSWORD | passwd --stdin $USERNAME &> /dev/null && echo $USERNAME is created
}
done
二、条件语句
1.while…do语句
作用:
条件为真执行动作
语句结构
while ture <!--条件为真-->
do <!--条件成立所作循环动作-->
done <!--结束-->
实例:
#!/bin/bash
while true
do
read -p "Please input word: " WORD
echo $WORD
done
2.until…do 语句
作用:
条件为假执行动作
语句结构
until false <!--条件为假-->
do <!--条件不成立所作循环动作-->
done <!--结束-->
案例:
#!/bin/bash
until [ "$USER" = "root" ]
do
read -p "Please input word: " WORD
echo $WORD
done
3.if…then…elif…then…else…fi 语句
作用:
多次判定条件执行动作
代码结构
if <!--首次判断定-->
then <!--条件成立执行动作-->
elif <!--当首次判定不成立时再次判定-->
then <!--条件成立执行动作-->
... <!--elif可以书写多次-->
else <!--所有条件不成立执行动作-->
fi <!--结束-->
案例
#!/bin/bash
if [ "$b" = "1" ]
then
echo $b
elif [ "$b" = "2" ]
then
echo $b
else
echo error
fi
练习题
题目要求
check_file.sh
please input filename: file
file is not exist
file is file
file is direcory
此脚本会一直询问直到用户输入exit为止
方案一
#!/bin/bash
while true
do
read -p "please input filename: " FILENAME
if [ "$FILENAME" = "exit" ]
then
exit
elif [ -e $FILENAME ]
then
[ -f $FILENAME ]&&{
echo $FILENAME is file
}||{
[ -d $FILENAME ]&&{
echo $FILENAME is directory
}
}
else
echo $FILENAME is not exist
fi
done
方案二
#!/bin/bash
while true
do
read -p "please input filename: " FILENAME
if [ "$FILENAME" = "exit" ]
then
exit
elif [ -e $FILENAME ]
then
if [ -f $FILENAME ]
then
echo $FILENAME is file
elif [ -d $FILENAME ]
then
echo $FILENAME is directory
fi
else
echo $FILENAME is not exist
fi
done
方案三
#!/bin/bash
CHECK()
{
if [ $1 $2 ]
then
echo $3
fi
}
while true
do
read -p "please input filename: " FILENAME
if [ "$FILENAME" = "exit" ]
then
exit
elif [ -e $FILENAME ]
then
CHECK -f $FILENAME "$FILENAME is file"
CHECK -d $FILENAME "$FILENAME is directory"
else
echo $FILENAME is not exist
fi
done
三、case
格式
case $1 in
word1|WORD1)
action1
;;
word2|WORD2)
action2
;;
*)
action3
esac
case与if条件语句相似,但执行流不同,if条件语句会将所有条件执行一遍,无论条件是否已经符合执行过了。
脚本练习:
题目要求
user_ctrl.sh
please input action:add
lee is exist ----- lee is exist ------> Please input username: exit ----->Please input action: exit
lee is not exist -----> Please input password ----> create lee ----- lee is created ---->Please input action : exit ----> exit
Please input action:del
Please input username: lee
lee is exist ------->delete lee ------>lee is deleted ----> Please input action:exit----->exit
lee is not exist -----> lee is not exist ----> Please input username:exit ---->Please input action : exit ----> exit
方案一
#!/bin/bash
ADD()
{
while true
do
read -p "Please input username: " USERNAME
if [ "$USERNAME" = "exit" ]
then
break
fi
id $USERNAME &> /dev/null &&{
echo $USERNAME is exist
}||{
read -p " Please input password: " PASSWORD
useradd $USERNAME
echo $PASSWORD | passwd --stdin $USERNAME &> /dev/null
echo $USERNAME is created
}
done
}
DEL()
{
while true
do
read -p "Please input username: " USERNAME
if [ "$USERNAME" = 'exit' ]
then
break
fi
id $USERNAME &> /dev/null &&{
userdel -r $USERNAME
echo $USERNAME is deleted
}||{
echo $USERNAME is not exist
}
done
}
while true
do
read -p "Please input action: " ACTION
case $ACTION in
add|ADD)
ADD
;;
del|DEL)
DEL
;;
exit|EXIT)
exit
;;
*)
echo input error
esac
方案二
while true
do
read -p "Please input username: " USERNAME
if [ "$USERNAME" = "exit" ]
then
break
elif id $USERNAME &> /dev/null
then
echo $USERNAME is exist
else
read -p " Please input password: " PASSWORD
useradd $USERNAME
echo $PASSWORD | passwd --stdin $USERNAME &> /dev/null
echo $USERNAME is created
fi
done
}
DEL()
{
while true
do
read -p "Please input username: " USERNAME
if [ "$USERNAME" = 'exit' ]
then
break
elif id $USERNAME &> /dev/null
then
userdel -r $USERNAME
echo $USERNAME is deleted
else
echo $USERNAME is not exist
fi
done
}
while true
do
read -p "Please input action: " ACTION
case $ACTION in
add|ADD)
ADD
;;
del|DEL)
DEL
;;
exit|EXIT)
exit
;;
*)
echo input error
esac
done
方案三
#!/bin/bash
USERACTION()
{
read -p "Please input username: " USER
case $USER in
exit|EXIT)
;;
*)
id $USER &> /dev/null && {
case $ACTION in
add|ADD)
echo $USER is exist
USERACTION
;;
del|DEL)
userdel -r $USER
echo $USER is deleted
esac
}||{
case $ACTION in
add|ADD)
read -p "Please input password:" PASSWD
useradd $USER
echo $PASSWD | passwd --stdin $USER
echo $USER is created
;;
del|DEL)
echo $USER is not exist
USERACTION
esac
}
esac
}
while true
do
read -p "Please input action: " ACTION
case $ACTION in
exit|EXIT)
exit
;;
add|ADD)
USERACTION
;;
del|DEL)
USERACTION
;;
*)
echo "ERROR: Wrong action, Pleasee input add | del |exit"
esac
done
四、expect
问题脚本
#!/bin/bash
read -p "what's your name: " NAME
read -p "How old are you " AGE
read -p "Which objective you study: " OBJ
read -p "Are you happy: " FEEL
echo $NAME is $AGE\'s old study $OBJ feel $FEEL
应答脚本一
#!/bin/bash
/mnt/ask.sh <<EOF
lee
18
linux
happy
EOF
该方式只能一行行准确对应否则会出现回答错误
应答脚本二
#!/usr/bin/expect
spawn /mnt/ask.sh
expect "name"
send "lee\r"
expect "old"
send "18\r"
expect "study"
send "linux\r"
expect "happy"
send "bad\r"
expect
应答脚本三
#!/usr/bin/expect
spawn /mnt/ask.sh
expect {
"name" { send "lee\r";exp_continue }
"old" { send "18\r";exp_continue }
"study" {send "linuxi\r";exp_continue }
"happy" { send "happy\r" }
}
expect eof
应答脚本四
#!/usr/bin/expect
set timeout 3
set NAME [ lindex $argv 0 ]
set AGE [ lindex $argv 1 ]
set OBJ [ lindex $argv 2 ]
set FEEL [ lindex $argv 3 ]
spawn /mnt/ask.sh
expect {
"name" { send "$NAME\r";exp_continue }
"old" { send "$AGE\r";exp_continue }
"study" {send "$OBJ\r";exp_continue }
"happy" { send "$FEEL\r" }
}
expect eof
应答脚本五
#!/bin/bash
/usr/bin/expect <<EOF
spawn /mnt/ask.sh
expect {
"name" { send "$1\r";exp_continue }
"old" { send "$2\r";exp_continue }
"study" {send "$3\r";exp_continue }
"happy" { send "$4\r" }
}
expect eof
EOF
脚本练习
host_list.sh
检测172.25.254.100-172.25.254.110网络是否开启
如果网络正常请生成解析列表hosts_list
格式如下
ip 主机名称
例如:172.25.254.1为开启状态主机名为westos_student1.westos.org
hosts_list中
172.25.254.1 westos_student1.westos.org
脚本
#!/bin/bash
AUTO()
{
/usr/bin/expect <<EOF
spawn ssh -l root 172.25.254.$IP hostname
expect {
"yes/no/" { send "yes\r";exp_continue }
"password" { send "westos\r" }
}
expect eof
EOF
}
for IP in {100..110}
do
ping -w1 172.25.254.$IP &> /dev/null && {
echo "172.25.254.$IP $(AUTO | tail -n 1)" >> host_list
}
done
执行脚本效果
五、break,continue,exit
contiue ##终止当此次前循环提前进入下个循环
break #终止当前所在语句所有动作进行语句外的其他动作
exit #脚本退出
#!/bin/bash
for I in {1..9}
do
if [ "$I" = "4" ]
then
echo luck number
continue
fi
echo $I
done
echo end
#!/bin/bash
for I in {1..9}
do
if [ "$I" = "4" ]
then
echo luck number
break
fi
echo $I
done
echo end
#!/bin/bash
for I in {1..9}
do
if [ "$I" = "4" ]
then
echo luck number
exit
fi
echo $I
done
echo end
六、返回值
#!/bin/bash
TEST()
{
echo 1
exit 3
echo 2
}
TEST
echo 4
#!/bin/bash
TEST()
{
echo 1
return 3
echo 2
}
TEST
echo 4
#!/bin/bash
TEST()
{
echo 1
return 3
echo 2
}
TEST
echo $?
echo 4
#!/bin/bash
TEST()
{
echo 1
echo 2
}
TEST
return 3
echo $?
echo 4