5、shell脚本中执行控制流

1.for语句

1.1 作用

为循环执行动作

1.2 for语句结构:

for 定义变量
do 使用变量,执行动作
done 结束标志

1.3 for语句基本格式

1.3.1 格式1

[root@server1 mnt]# vim for.sh 
#!/bin/bash
 for I in {1..10}
 do
 echo $I
 done 
[root@server1 mnt]# sh for.sh 
1
2
3
4
5
6
7
8
9
10 
[root@server1 mnt]# vim for.sh   
 #!/bin/bash
 for I in {10..1}  还可以倒着写,从10到1
 do
 echo $I
 done
[root@server1 mnt]# sh for.sh 
10
9
8
7
6
5
4
3
2
1	

1.3.2 格式2

[root@server1 mnt]# vim for.sh
#!/bin/bash
 for I in `seq 1 10`
 do 
 echo $I
 done 
[root@server1 mnt]# sh for.sh 
1
2
3
4
5
6
7
8
9
10 
[root@server1 mnt]# vim for.sh 
 #!/bin/bash
 for I in `seq 1 2 10`   可以设置步长,2为步长
  do
  echo $I
 done
[root@server1 mnt]# sh for.sh     
1
3
5
7
9

1.3.3 格式3

[root@server1 mnt]# vim for.sh 
  #!/bin/bash
  for ((I=1;I<=10;I++))   I++ 表示I每次自加1
  do 
  echo $I
 done 
[root@server1 mnt]# sh for.sh 
1
2
3
4
5
6
7
8
9
10
[root@server1 mnt]# vim for.sh
 #!/bin/bash
 for ((I=10;I>0;I--))   倒着写
 do
 echo $I
 done
[root@server1 mnt]# sh for.sh 
10
9
8
7
6
5
4
3
2
1
0

2.判断循环语句

while …do语句
作用:
条件为真执行动作
语句结构
while ture 条件为真
do 条件成立所循环的动作
down

[root@server1 mnt]# vim while.sh 
   #!/bin/bash
   for I in {1..10}
   do
    while  [ "$I" = "4" ]  
    do
    read -p "Please input number: " I
   echo $I
  done
 echo $I 
done
[root@server1 mnt]# sh while.sh 
1
2
3
Please input number: 4
4
Please input number: 4
4
[root@server1 mnt]# vim while.sh 
   #!/bin/bash
   for I in {1..10}
   do
    while  [ "$I" = "4" ]  
    do
   echo $I   一直循环4
  done
 echo $I 
done
[root@server1 mnt]# sh while.sh
4
4
4
4
4
4
4
4
[root@server1 mnt]# vim while.sh 
  #!/bin/bash
   while true  条件成立
   do
    read -p "Please input word: " WORD
   while [ "$WORD" = "exit" ]
  do
   exit
  done 
  echo $WORD
  done
[root@server1 mnt]# sh while.sh 
Please input word: lee
lee
Please input word: westos
westos
Please input word: exit

[root@server1 mnt]# vim while.sh    
 6 #!/bin/bash
  7 until false    表示当条件不成立的时候
  8 do
  9  read -p "Please input word: " WORD
 10  while [ "$WORD" = "exit" ]
 11 do
 12  exit
 13 done
 14 
 15  echo $WORD
 16 done
[root@server1 mnt]# sh while.sh    执行
Please input word: lee
lee
Please input word: poo
poo
Please input word: exit

3.多条件判断语句

if…then…elif…then…else…fi 语句
if 首次判定
then 条件成立执行的动作
elif 当首次判定不成立时再次判定
then 条件成立执行的动作
… elif可以书写多次
else 所有条件不成立执行的动作
fi 结束

[root@server1 mnt]# vim if.sh
  #!/bin/bash
  if [ -z "$1"]
   then
  echo "Please input a number following $0 !!"
  elif [ "$1" -lt "0" ]
   then
  echo no
 elif [ "$1" -gt "10" ]
 then
 echo no 
 else
 echo yes 
  fi
[root@server1 mnt]# sh if.sh  执行
Please input a number following if.sh !!
[root@server1 mnt]# sh if.sh 11
no
[root@server1 mnt]# sh if.sh 10
yes

如何判断过滤成数字

[root@server1 mnt]# grep [[:alpha:][:punct:]] /etc/passwd && echo no || echo yes

4.shell中的选择语句

格式
	case $1 in
		word1|WORD1)
		action1                             ##动作1
		;;
			word2|WORD2)
			action2							    ##动作2
			;;
			*)
			action3								##动作3
		esac
 #!/bin/bash
  case $1 in
  westos|WESTOS)
  echo linux
 ;;
 linux|LINUX)
 echo westos
 ;;
 *)
 echo error
 esac
 [root@server1 mnt]# sh case.sh westos 执行
linux
[root@server1 mnt]# sh case.sh linux
westos
[root@server1 mnt]# sh case.sh 
error

5. shell中的自动应当方案

问题:
[root@server1 mnt]# vim ask.sh   
#!/bin/bash
	read -p "what's your name:" NAME    
	read -p "How old are you: " AGE 
	read -p "Which subject: " OBJ
	read -p "Are you happy? " FEEL
	echo $NAME is $AGE\'s old study $OBJ feel $FEEL
[root@server1 mnt]# sh ask.sh  执行,交互式
what's your name:lee
How old are you: 30
Which subject: shell
Are you ok? happy
lee is 30's old study shell feel happy

[root@server1 mnt]# vim test.sh       多行录入,实现自动应答
#!/bin/bash
 /mnt/ask.sh << EOF
 lee
 20
 linux
 happy
EOF
[root@server1 mnt]# sh test.sh   执行
lee is 20's old study linux feel happy
[root@server1 mnt]# vim ask.sh     如果将其中一个问题注释
#!/bin/bash
	read -p "what's your name:" NAME    
	#read -p "How old are you: " AGE    注释掉
	read -p "Which subject: " OBJ
	read -p "Are you happy? "  FEEL
	echo $NAME is $AGE\'s old study $OBJ feel $happy
[root@server1 mnt]# sh test.sh   执行多行录入自动应答,发现结果混乱
lee is 20's old study linux feel happy     用多行录入实现自动应答,只能解决顺序不变问题都会出现的
	

上述问题可用expect解决

[root@server1 mnt]# yum install expect -y    安装
[root@server1 mnt]# vim answer.exp
  1 #!/usr/bin/expect 
  2 spawn /mnt/ask.sh     
  3 expect {                                遇到的问题及应答
  4   "name" { send "lee\r";exp_continue }
  5   "old" { send "20\r";exp_continue }
  6   "subject" {send "shell\r";exp_continue }
  7   "happy" { send "happy\r" }
  8 }
  9 
 10 expect eof   表示回答问题以后,立即退出expect环境,如果是interact表示不退出expect环境
[root@server1 mnt]# expect answer.exp   执行
spawn /mnt/ask.sh
what's your name:lee
How old are you: 20
Which subject: shell
Are you happy? happy
lee is 20's old study shell feel happy

[root@server1 mnt]# vim ask.sh 
  #!/bin/bash
   read -p "what's your name:" NAME
   #read -p "How old are you: " AGE     注释掉
   read -p "Which subject: " OBJ
  read -p "Are you happy? " FEEL
  echo $NAME is $AGE\'s old study $OBJ feel $FEEL
[root@server1 mnt]# expect answer.exp    执行
spawn /mnt/ask.sh
what's your name:lee
Which subject: shell
Are you happy? happy
lee is 's old study shell feel happy      即使注释掉一行回答也是正确的

优化脚本
[root@server1 mnt]# vim answer.exp
1 #!/usr/bin/expect
  2 set timeout 2    表示停顿超过2s忽略
  3 set NAME [ lindex $argv 0 ]   设置变量,$argv 0 表示answer.exp脚本后面跟的第一串字符
  4 set AGE [ lindex $argv 1 ]      $argv 1表示answer.exp脚本后面跟的第二串字符
  5 set OBJ [ lindex $argv 2 ]    $argv 2表示answer.exp脚本后面跟的第三串字符
  6 set FEEL [ lindex $argv 3 ]   $argv 3 表示answer.exp脚本后面跟的第四串字符
  7 spawn /mnt/ask.sh
  8 expect { 
  9   "name" { send "$NAME\r";exp_continue }     \r表示回车
 10   "old" { send "$AGE\r";exp_continue }
 11   "subject" {send "$OBJ\r";exp_continue }
 12   "happy" { send "$FEEL\r" }
 13 }
 14 
 15 expect eof 
[root@server1 mnt]# expect answer.exp    后面没跟,答案都是空的
spawn /mnt/ask.sh
what's your name:
Which subject: 
Are you happy? 
is 's old study feel  
[root@server1 mnt]# expect answer.exp lee 20 
spawn /mnt/ask.sh
what's your name:lee
How old are you: 20
Which subject: 
Are you happy? 
lee is 20's old study feel

如何将shell和expect结合起来

[root@server1 mnt]# vim test.sh 
 #!/bin/bash 
 /usr/bin/expect << EOF      
 spawn /mnt/ask.sh
 expect {
 "name" { send "$1\r";exp_continue}          EOF中间内容都在expect环境执行
 "old" { send "$2\r";exp_continue}
 "subject" { send "$3\r";exp_continue}
 "happy" { send "$4\r"}
  }
 expect eof
 EOF
 echo hello westos 
 date
[root@server1 mnt]# sh  test.sh lee 30 linux happy   执行
spawn /mnt/ask.sh
what's your name:lee
How old are you: 30
Which subject: linux
Are you happy? happy
lee is 30's old study linux feel happy
hello westos
Tue Oct 11 05:06:58 CST 2022 

6、shell中的控制器

break 终止当此次循环提前进入下个循环
continue 终止当前所在语句所有动作进行语句外的其他动作
exit 脚本退出
return 表示退出函数,函数以外的继续执行

6.1 exit

[root@server1 mnt]# ls
test.sh
[root@server1 mnt]# echo $?       $?表示退出直
0
[root@server1 mnt]# vim test.sh   
#!/bin/bash
ls /mnt &> /dev/null
[root@server1 mnt]# sh test.sh   
[root@server1 mnt]# echo $?    退出直为0
0
[root@server1 mnt]# vim test.sh 
#!/bin/bash
ls /mnt &> /dev/null
exit 1     设置退出直为1
[root@server1 mnt]# sh test.sh 
[root@server1 mnt]# echo $?     退出直为1
1
[root@server1 mnt]# vim test.sh 
#!/bin/bash
   for I in {1..10}
   do
    if [ "$I" = "4" ]
   then
    echo luck number
    exit     
   fi
   
   echo $I
  
  done
  
  echo end
[root@server1 mnt]# sh test.sh    遇到exit直接退出
1
2
3
luck number

6.2 continue

[root@server1 mnt]# vim test.sh 
#!/bin/bash
   for I in {1..10}
   do
    if [ "$I" = "4" ]     表示终止"$I" = "4"的循环,到continue为止,后面的动作echo $I 就放弃了,循环"$I" = "4"外的循化依然执行
   then
    echo luck number
    continue   
   fi
   
   echo $I    
  
  done
  
  echo end
[root@server1 mnt]# sh test.sh 
1
2
3
luck number           
5
6
7
8
9
10
end

6.3 break

[root@server1 mnt]# vim test.sh 
#!/bin/bash
   for I in {1..10}
   do
    if [ "$I" = "4" ]
   then
    echo luck number
    break           表示终止所在for循环,for循环以外的仍然执行
   fi
   
   echo $I
  
  done
  
  echo end
[root@server1 mnt]# sh test.sh   执行
1
2
3
luck number
end

6.4 return

6 #!/bin/bash
  7 TEST()
  8 {
  9 for I in {1..10}
 10 do
 11  if [ "$I" = "4" ]
 12  then
 13   echo luck number
 14   return         表示退出函数,函数以外的继续执行
 15  fi
 16  
 17  echo $I
 18 
 19 done
 20 
 21 echo end
 22 }
 23 TEST
 24 echo ========================== 
[root@server1 mnt]# sh test.sh   执行
1
2
3
luck number    
========================== 

7.练习

7.1字符长度判定

在westos.txt中输出字符长度小于8的每一列
在这里插入图片描述
/etc/passwd文件的第六列没有home关键字并且以bash结尾的行

[root@server1 mnt]# awk -F : '$6!~/home/&&/bash$/{print}' /etc/passwd 
root:x:0:0:root:/root:/bin/bash

7.2批量添加用户

执行 usercreate.sh userlist ,userlist里面的用户全部建立出来,用户存在报错,用户不存在建立用户并且密码设置为westos

[root@server1 mnt]# vim userlist
1 user1
2 user2
3 user3

[root@server1 mnt]# vim usercreate.sh  执行
 1 ##################
  2 # AUthor
  3 # Create_Time:    2022/10/11
  4 ##################
  5 
  6 #!/bin/bash
  7 [ -z "$1" ] && {
  8   echo "Please input userlist file follow $0 !!"
  9   exit
 10 }
 11 
 12 [ ! -e "$1" ] && {
 13   echo "$1 is not exist"
 14   exit
 15 }
 16 
 17 for USERNAME in `cat $1`
 18 do
 19  id $USERNAME &> /dev/null && {
 20    echo $USERNAME is exist !!
 21  }||{
 22    useradd $USERNAME
 23    echo westos | passwd --stdin $USERNAME
 24   }
 25 done
[root@server1 mnt]# sh usercreate.sh userlis
userlis is not exist
[root@server1 mnt]# sh usercreate.sh userlist 
Changing password for user user1.
passwd: all authentication tokens updated successfully.
Changing password for user user2.
passwd: all authentication tokens updated successfully.
Changing password for user user3.
passwd: all authentication tokens updated successfully.
[root@server1 mnt]# sh usercreate.sh userlist 
user1 is exist !!
user2 is exist !!
user3 is exist !!

7.3文件类型判定

在这里插入图片描述

[root@server1 mnt]#  vim create_filetype.sh
  1 ##################
  2 # AUthor
  3 # Create_Time:    2022/10/12
  4 ##################
  5 
  6 #!/bin/bash
  7 if [ -z "$*" ]
  8 then
  9   echo Please input filename following $0 !!
 10 elif [ ! -e "$*" ]
 11 then
 12   echo file is not exist !!
 13 elif [ -L "$*" ]
 14 then
 15  echo $* is link
 16 elif [ -f "$*" ]
 17 then
 18  echo $* is  common file
 19 elif [ -d "$*" ]
 20 then
 21  echo $* is directory
 22 fi
[root@server1 mnt]# sh create_filetype.sh 
Please input filename following create_filetype.sh !!
[root@server1 mnt]# sh create_filetype.sh /mnt/
/mnt/ is directory    
[root@server1 mnt]# sh create_filetype.sh /mnt/test.sh 
/mnt/test.sh is common file
 

7.4 查找字符长度

取出文件westos.txt内容单词字母个数小于8的
cat westos.txt
Operating System: Red Hat Enterprise Linux 8.2 (Ootpa)

[root@server1 mnt]# vim westos.sh
 1 ##################
  2 # AUthor
  3 # Create_Time:    2022/10/12
  4 ##################
  5 
  6 #!/bin/bash
  7 if [ -n "$1" ]
  8 then
  9   for WORD in `cat $1`
 10   do
 11    LENGTH=`echo -n $WORD|wc -m`     -n表示去掉换行符
 12    if [ $LENGTH -lt "8" ]    
 13    then
 14     echo $WORD
 15    fi
 16   done
 17 else
 18  echo Please input file following $0 !!
 19 fi
[root@server1 mnt]# sh westos.sh westos.txt    执行
System:
Red
Hat
Linux
8.2
(Ootpa)

7.4 网络检测脚本

检测网络172.25.254.1…10网络是否通畅

[root@server1 mnt]# vim check_net.sh
  1 ##################
  2 # AUthor
  3 # Create_Time:    2022/10/12
  4 ##################
  5 
  6 #!/bin/bash
  7 for HOST in {1..10}  50
  8 do
  9  ping -c1 -w1 172.25.254.$HOST &> /dev/null && {
 10   echo 172.25.254.$HOST is up 
 11  }||{
 12      echo 172.25.254.$HOST is down 
 13  } 
 14 done
[root@server1 mnt]# sh check_net.sh   执行
172.25.254.1 is down
172.25.254.2 is down
172.25.254.3 is down
172.25.254.4 is down
172.25.254.5 is down
172.25.254.6 is down
172.25.254.7 is down
172.25.254.8 is down
172.25.254.9 is down
172.25.254.10 is down
172.25.254.50 is up    
 

7.5 自动应答脚本

在这里插入图片描述

[root@server1 mnt]# vim check_host.sh
##################
# AUthor
# Create_Time:    2022/10/12
##################

#!/bin/bash
AUTH_SSH()
{
/usr/bin/expect <<EOF
spawn ssh -l root $1 hostname      $1代表AUTH_SSH函数后的第一串字符
expect {
"yes/no" { send "yes\r";exp_continue }
"password" { send "westos\r"}
}
expect eof
EOF
}

[ -z "$*" ] && {
  echo "Please input ip address following $0 !!"     
  exit
}
ping -c1 -w1 $* &> /dev/null && {
AUTH_SSH $* | tail -n 1       AUTH_SSH $*表示 $1
}||{
 echo "$* is down"
}
[root@server1 mnt]# sh check_host.sh  172.25.254.50  执行
foundation50
[root@server1 mnt]# sh check_host.sh  172.25.254.51
172.25.254.51 is down

7.6 软件管理脚本

在这里插入图片描述

##################
# AUthor
# Create_Time:    2022/10/12
##################

#!/bin/bash
case $1 in
  install)
  read -p "Please input software: " SOFTWARE
  dnf list $SOFTWARE &> /dev/null && {
   rpm -q $SOFTWARE &> /dev/null && {
     echo $SOFTWARE is installed
    }||{
      echo dnf install $SOFTWARE -y &> /dev/null && echo $SOFTWARE install successful !!
     }
  }||{
    echo $SOFTWARE is not exist !!
  }
  ;;
  delete)
  read -p "Please input software: " SOFTWARE
  dnf list $SOFTWARE &> /dev/null && {
   rpm -q $SOFTWARE &> /dev/null && {
     dnf remove $SOFTWARE -y &> /dev/null && echo $SOFTWARE is delete successful !!
  }||{
    echo $SOFTWARE is not installed
 }
 }||{
    echo $SOFTWARE is not exist 
  }
  ;;
  *)
  echo "Please input install or delete following $0 !!"
esac
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小莫细说linux

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值