shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect

1.for 语句

for NUM in 1 2 3
for NUM in {1…3}
for NUM in `seq 1 3` 或者 for NUM in `seq 1 2 10`
do
done

注:seq 设定步长,每隔几个做一次

(1)正序输出1-10

#!/bin/bash
for i in {1..10}
do
        echo $i
done

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第1张图片
或者

#!/bin/bash
for i in `seq 1 10`
do
        echo $i
done

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第2张图片
shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第3张图片
(2)输出1,2,3

#!/bin/bash
for i in 1 2 3
do
        echo $i
done

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第4张图片
在这里插入图片描述
(3)利用for循环查看/mnt下的所有文件或子目录

#!/bin/bash
for i in `ls /mnt`
do
        echo $i
done

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第5张图片
测试:

[root@shell_example mnt]# vim test.sh
[root@shell_example mnt]# sh test.sh
calculator.sh
numtest.sh
test.sh
time_count1.sh
time_count.sh
[root@shell_example mnt]# ls
calculator.sh  numtest.sh  test.sh  time_count1.sh  time_count.sh

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第6张图片
在这里插入图片描述
(4)输出1-10之间的奇数

#!/bin/bash
for i in `seq 1 2 10`
do
        echo $i
done

在这里插入图片描述
测试:

[root@shell_example mnt]# vim jishu.sh
[root@shell_example mnt]# sh jishu.sh
1
3
5
7
9

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第7张图片
(5)输出1-10之间的偶数

#!/bin/bash
for i in `seq 2 2 10`
do
        echo $i
done

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第8张图片
测试:

[root@shell_example mnt]# vim jishu.sh
[root@shell_example mnt]# sh jishu.sh
2
4
6
8
10

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第9张图片
练习1:用for循环设计一个30秒的倒计时的定时器

#!/bin/bash
[ -z "$1" ]&&{
        echo ERROR
        exit
}
clear
for ((SEC=$1;SEC>0;SEC--))
do
        echo -n "After ${SEC}s is end "
        echo -ne "\r"
        sleep 1
done

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第10张图片
测试:

[root@shell_example mnt]# vim countdown.sh
[root@shell_example mnt]# sh countdown.sh 
ERROR
[root@shell_example mnt]# sh countdown.sh 30

在这里插入图片描述
在这里插入图片描述
注意:
"After ${SEC}s is end "后一定要有空格,因为两位数和一位数所占的字符数不同,需要空格来占位

练习2:编写一个脚本,使其在没有输入任何内容的时候报错,连通主机是输出ip is up ,不能连通时输出ip is down

首先编辑一个文件写入需要测试的ip

[root@shell_example mnt]# vim ipfile
[root@shell_example mnt]# cat ipfile

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第11张图片
脚本如下:

#!/bin/bash
[ -z "$1" ] && {
        echo "plesae input filename"
        exit
}
for i in `cat $1`
do
        ping -c 1 -w 1 $i  &>/dev/null  && {
                echo $i is up
        } || {
                echo $i is down
        }
done

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第12张图片
测试:

[root@shell_example mnt]# vim ip_check.sh
[root@shell_example mnt]# sh ip_check.sh 
plesae input filename
[root@shell_example mnt]# sh ip_check.sh ipfile 
172.25.254.1 is down
172.25.254.3 is down
172.25.254.10 is down
172.25.254.68 is up
172.25.254.127 is up

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第13张图片
第二种:

#!/bin/bash
[ -z "$1" ] && {
        echo "plesae input filename"
        exit
}
Max_line=`sed -n '$=' $1`
for i in $(seq 1 $Max_Line)
do
        ip=`sed -n "${i}p" $1`
         ping -c 1 -w 1 $ip  &>/dev/null  && {
                echo $i is up
        } || {
                echo $i is down
        }
done

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第14张图片
2.while 语句

while 条件
do
done

while表示条件为真时做什么
until表示条件为假时做什么

(1)编写一个脚本,输入什么输出什么

#!/bin/bash
while true
do
        read -p "Please input a word: " WORD
        echo $WORD
done

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第15张图片
测试:

[root@shell_example mnt]# vim whiletest.sh
[root@shell_example mnt]# sh whiletest.sh 
Please input a word: hello
hello
Please input a word: test
test
Please input a word: hahah
hahah
Please input a word: ^C

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第16张图片
(2)当第一个条件为until true时不会有输出结果

#!/bin/bash
until true
do
        read -p "Please input a word: " WORD
        while [ "$WORD" = "exit" ]
        do
                echo bye
                exit 0
        done
        echo $WORD      
done

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第17张图片
测试:

[root@shell_example mnt]# vim whiletest.sh
[root@shell_example mnt]# sh whiletest.sh 

在这里插入图片描述
(3)当第一个条件为until false时正确输出

#!/bin/bash
until false   ##条件不成立时不执行
do
        read -p "Please input a word: " WORD
        while [ "$WORD" = "exit" ]
        do
                echo bye
                exit 0
        done
        echo $WORD      
done

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第18张图片
测试:

[root@shell_example mnt]# vim whiletest.sh
[root@shell_example mnt]# sh whiletest.sh 
Please input a word: hello
hello
Please input a word: new
new
Please input a word: old
old
Please input a word: exit
bye

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第19张图片
3.if 语句

if
then
elif
then

else
fi

例1:编写一个脚本当输入a时输出apple,输入b时输出banana,输入其他字符时输出error

#!/bin/bash
if
[ "$1" = "a" ]
then
        echo apple
elif
[ "$1" = "b" ]
then
        echo banana
else
        echo error
fi

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第20张图片
测试:

[root@shell_example mnt]# vim iftest.sh
[root@shell_example mnt]# sh iftest.sh b
banana
[root@shell_example mnt]# sh iftest.sh a
apple
[root@shell_example mnt]# sh iftest.sh 
error

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第21张图片
练习1:编写一个脚本当输入文件时判断他的类型,并将结果输出

#!/bin/bash
while true
do
        read -p "please input a filename: " FILE
        [ -e "$FILE" ] || {
                echo "this file is not exist"
}
if 
        [ -L "$FILE" ]
then
        echo "$FILE is a link "
elif
        [ -f "$FILE" ]
then
        echo "$FILE is a file "
elif
        [ -d "$FILE" ]
then
        echo "$FILE is a directory " 
elif
        [ -b "$FILE" ]
then
        echo "$FILE is a block "
elif
        [ -c "$FILE" ]
then
        echo "$FILE is a character "
elif
        [ -s "$FILE" ]
then
        echo "$FILE is a socket "
elif
        [ "$FILE" = "exit" ]
then
        exit
fi

done

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第22张图片
测试:

[root@shell_example mnt]# vim filetype.sh
[root@shell_example mnt]# sh filetype.sh 
please input a filename: /mnt
/mnt is a directory 
please input a filename: /etc/passwd
/etc/passwd is a file 
please input a filename: exit 

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第23张图片
练习2:用if语句编写一个脚本,设计一个1分10秒的倒计时的定时器

#!/bin/bash
SEC=10
MIN=1
for ((;SEC>=0;SEC--))
do
        if
        [ "$SEC" -eq "0" -a "$MIN" -eq "0" ]
        then
                exit 0
        elif
        [ "$SEC" -eq "0" -a "$MIN" -ge "0" ]
        then
                echo -n "After "$MIN"m:"$SEC"s is end "
                echo -ne "\r"
                SEC=59
                ((MIN--))
                sleep 1
                clear
        fi
        echo "After "$MIN"m:"$SEC"s is end "
        echo -ne "\r"
        sleep 1
        clear
done

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第24张图片
测试:
在这里插入图片描述
在这里插入图片描述
4.case 语句

case
word1 )
action1
;;
word2)
action2
\;;
*)
action_last
esac

例:
编写一个脚本,输入a返回apache,输入b返回backup,输入c返回chrony,输入其他字符时返回error

#!/bin/bash
case $1 in
        a)
        echo apache
        ;;
        b)
        echo backup
        ;;
        c)
        echo chrony
        ;;
        *)
        echo error
esac

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第25张图片
测试:

[root@shell_example mnt]# vim casetest.sh
[root@shell_example mnt]# sh casetest.sh 
error
[root@shell_example mnt]# sh casetest.sh a
apache
[root@shell_example mnt]# sh casetest.sh b
backup
[root@shell_example mnt]# sh casetest.sh c
chrony

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第26张图片
比较case语句和if语句:
case和if功能相同但效率不一样,if需要判断多次,一个一个查找对应的条件,而case会直接查找想要的条件
在字符匹配的时候用case
在判断的时候用if

(1)这里可以利用之前编写的iftest.sh脚本,和刚刚编写的casetest.sh脚本作比较,两者的功能是一样的,都是输入一个字符返回一个对应的字符串
shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第27张图片
shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第28张图片
(2)我们可以sh -x执行脚本观察循环的顺序,可以看到执行if循环额脚本时是有先后顺序的,这个顺序就是见本中编写的前后顺序,当输入b时循环了两次才找到对应的字符串

[root@shell_example mnt]# sh -x iftest.sh a
+ '[' a = a ']'
+ echo apple
apple
[root@shell_example mnt]# sh -x iftest.sh b
+ '[' b = a ']'
+ '[' b = b ']'
+ echo banana
banana

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第29张图片
(3)但是在执行case语句时没有先后顺序,不管输入哪个字符都只循环一次

[root@shell_example mnt]# sh -x casetest.sh a
+ case $1 in
+ echo apache
apache
[root@shell_example mnt]# sh -x casetest.sh b
+ case $1 in
+ echo backup
backup

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第30张图片
5.expect

expect 是自动应答命令用于交互式命令的自动执行
spawn 是 expect 中的监控程序,其运行后会监控命令提出的交互问题
send 发送问题答案给交互命令
“\r” 表示回车
exp_continue 表示当问题不存在时继续回答下面的问题
expect eof 表示问题回答完毕退出 expect 环境
interact 表示问题回答完毕留在交互界面
set NAME [ lindex $argv n ] 定义变量

实验:

1.创建两个脚本,一个作为问题,一个作为答案,改变其中一个脚本的信息另一个不变时和会出现问题与但阿不匹配的状况

(1)创建一个脚本作为提问的,给他加上可执行权限,运行结果如下

#!/bin/bash
read -p "What's your name: " NAME
read -p "How old are you: " AGE
read -p "Which objective study: " OBJ
read -p "Are you happy? " FEEL
echo $NAME is $AGE\'s old study $OBJ feel $FEEL

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第31张图片
测试:

[root@shell_example mnt]# vim ask.sh
[root@shell_example mnt]# chmod +x ask.sh
[root@shell_example mnt]# sh ask.sh
What's your name: yyy
How old are you: 18
Which objective study: linux
Are you happy? happy
yyy is 18's old study linux feel happy

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第32张图片
(2)再创建一个脚本将上一个脚本中问题的答案重定向到ask.sh中去

#!/bin/bash
/mnt/ask.sh <

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第33张图片
测试:

[root@shell_example mnt]# vim answer.sh
[root@shell_example mnt]# sh answer.sh 
haha is 10's old study java feel sad

在这里插入图片描述
(3)此时将ask.sh中的某一个问题注释掉,另一个脚本中的内容不做任何改变,运行answer.sh脚本后会出现问题与答案不匹配的情况

#!/bin/bash
read -p "What's your name: " NAME
#read -p "How old are you: " AGE
read -p "Which objective study: " OBJ
read -p "Are you happy? " FEEL
echo $NAME is $AGE\'s old study $OBJ feel $FEEL

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第34张图片
测试:

[root@shell_example mnt]# vim ask.sh
[root@shell_example mnt]# sh answer.sh 
haha is 's old study 10 feel java

在这里插入图片描述
2.利用expect创建两个脚本一个时问题一个是答案,尽管改变了其中一个的信息两个脚本相匹配时也不会出错

(1)下载安装包

[root@shell_example mnt]# yum install expect.x86_64 -y

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第35张图片
(2)下载完成后直接可以使用expect命令,这里退出要用exit

[root@shell_example mnt]# expect
expect1.1> exit

在这里插入图片描述
(3)查看expect用的解释环境

[root@shell_example mnt]# which expect
/usr/bin/expect

在这里插入图片描述
(4)编辑test.exp文件并写入答案(将ask.sh中的注释还原),这里的脚本文件必须以.exp结尾

#!/usr/bin/expect
spawn /mnt/ask.sh
expect "name"
send "yue\r"
expect "old"
send "18\r"
expect "objective"
send "uklele\r"
expect "happy"
send "very happy\r"
interact

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第36张图片
测试:

[root@shell_example mnt]# vim test.exp
[root@shell_example mnt]# expect test.exp 
spawn /mnt/ask.sh
What's your name: yue
How old are you: 18
Which objective study: uklele
Are you happy? very happy
yue is 18's old study uklele feel very happy

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第37张图片
3.在test.exp中定义变量

#!/usr/bin/expect
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"
expect "old"
send "$AGE\r"
expect "objective"
send "$OBJ\r"
expect "happy"
send "$FEEL\r"
expect eof

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第38张图片
测试:
执行脚本时缺少几个变量就会有行的答案为空
(1)变量为空时没有答案输出

[root@shell_example mnt]# vim test.exp
[root@shell_example mnt]# expect test.exp 
spawn /mnt/ask.sh
What's your name: 
How old are you: 
Which objective study: 
Are you happy? 
is 's old study feel

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第39张图片
(2)输入合适个数的变量

[root@shell_example mnt]# expect test.exp yue 18 uklele happy
spawn /mnt/ask.sh
What's your name: yue
How old are you: 18
Which objective study: uklele
Are you happy? happy
yue is 18's old study uklele feel happy

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第40张图片
(3)将ask.sh中的某一行注释掉,再次执行test.exp这是在被注释掉的问题那行会停顿一段时间,找不到答案之后他会输出匹配出的错误结果

[root@shell_example mnt]# vim ask.sh
[root@shell_example mnt]# expect test.exp yue 18 uklele happy
spawn /mnt/ask.sh
What's your name: yue
How old are you: 18
Are you happy? uklele
happy
yue is 18's old study feel uklele

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第41张图片
shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第42张图片
4.设置如果问题不存在继续回答下面的问题

脚本expect自动打开自己的解释环境,和shell不通用
set timeout 5 提高脚本的执行效率,问题回答不上来就直接放弃

(1)将ask.sh中的内容还原,编辑test.exp并且执行脚本

#!/usr/bin/expect
set NAME [ lindex $argv 0 ]
set AGE  [ lindex $argv 1 ]
set OBJ  [ lindex $argv 2 ]
set FEEL [ lindex $argv 3 ]
set timeout 5
spawn /mnt/ask.sh
expect {
        "name"        {send "$NAME\r" ; exp_continue }
        "old"         {send "$AGE\r"  ; exp_continue }
        "objective"   {send "$OBJ\r"  ; exp_continue }
        "happy"       {send "$FEEL\r" }
}
expect eof

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第43张图片
测试:

[root@shell_example mnt]# vim test.exp
[root@shell_example mnt]# vim ask.sh
[root@shell_example mnt]# expect test.exp yue 18 uklele happy
spawn /mnt/ask.sh
What's your name: yue
How old are you: 18
Which objective study: uklele
Are you happy? happy
yue is 18's old study uklele feel happy

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第44张图片
(2)将ask.sh中的一行注释掉,再次运行脚本时被注释掉的问题不会再次出现,所有的问题与答案也会匹配
shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第45张图片
测试:

[root@shell_example mnt]# vim ask.sh
[root@shell_example mnt]# vim test.exp
[root@shell_example mnt]# expect test.exp yue 18 uklele happy/
spawn /mnt/ask.sh
What's your name: yue
How old are you: 18
Are you happy? happy
yue is 18's old study feel happy

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第46张图片
6.语句控制器

(1)exit n 脚本退出(所在环境),退出值为 n
(2)break 退出当前循环(当前所有循环)
(3)continue 提前结束循环内部的命令,但不终止循环(打破当前循环,进入到下一次循环)

实验:

(1)当叫脚本中没有使用任何控制语句时结果如下

#!/bin/bash
for i in {1..10}
do
        if 
        [ "$i" = "5" ]
        then
        echo $i
        fi
        echo $i
done

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第47张图片
测试:

[root@shell_example mnt]# vim test.sh
[root@shell_example mnt]# sh test.sh

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第48张图片
(2)exit 0 退出当前脚本

#!/bin/bash
for i in {1..10}
do
        if 
        [ "$i" = "5" ]
        then
        exit 0
        fi
        echo $i
done

echo westos!!!!!!

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第49张图片
测试:

[root@shell_example mnt]# vim test.sh
[root@shell_example mnt]# sh test.sh
1
2
3
4

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第50张图片
(3)break 退出当前循环提前进行后面的

#!/bin/bash
for i in {1..10}
do
        if 
        [ "$i" = "5" ]
        then
        break
        fi
        echo $i
done

echo westos!!!!!!

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第51张图片
测试:

[root@shell_example mnt]# vim test.sh
[root@shell_example mnt]# sh test.sh
1
2
3
4
westos!!!!!!

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第52张图片
(4)continue 打破当前循环,但不结束

#!/bin/bash
for i in {1..10}
do
        if 
        [ "$i" = "5" ]
        then
        continue
        fi
        echo $i
done

echo westos!!!!!!

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第53张图片
测试:

[root@shell_example mnt]# vim test.sh
[root@shell_example mnt]# sh test.sh

shell中的循环语句(for,while,if,case)、语句控制器(exit,break,continue)以及expect_第54张图片

你可能感兴趣的:(Linux学习)