本节内容

1. shell流程控制

2. for语句

3. while语句

4. break和continue语句

5. case语句

6. shell编程高级实战

shell流程控制

流程控制是改变程序运行顺序的指令。linux shell有一套自己的流程控制语句,其中包括条件语句(if),循环语句(for,while),选择语句(case)。下面我将通过例子介绍下,各个语句使用方法

if语句

格式:

格式:if list; then list; [ elif list; then list; ] ... [ else list; ] fi

1.1 单分支

if 条件表达式; then
命令
fi

实例:

#!/bin/bash
N=10
if [ $N -gt 5 ]; then
  echo yes
fi

# bash test.sh
yes

1.2 双分支

if 条件表达式; then
  命令
else
  命令
fi

实例1:

#!/bin/bash
N=10
if [ $N -lt 5 ]; then
  echo yes
else
  echo no
fi

# bash test.sh
no

实例2:判断crond进程是否正在运行

-v: 表示取反

-c: 即count,取代通常的输出,显示行数

#!/bin/bash
NAME=crond
NUM=$(ps aux | grep $NAME | grep -vc grep)
if [ $NUM -eq 1 ]; then
  echo "$NAME running."
else
  echo "$NAME is not running!"
fi

实例3:检查主机是否在线

-c:表示发送几次包

-w:表示等待时间。当试图检测不可达主机时此选项很有用。

#!/bin/bash
if ping -c 1 192.168.1.1 >/dev/null; then 
  echo "OK." else   echo "NO!" fi

if 语句可以直接对命令状态进行判断,就省去了获取$?这一步!

1.3 多分支

if 条件表达式; then
  命令
elif 条件表达式; then
  命令
else
  命令
fi

当不确定条件符合哪一个时,就可以把已知条件判断写出来,做相应的处理。

实例1:

$1:表示接受用户输入参数

#!/bin/bash
N=$1
if [ $N -eq 3 ]; then
  echo "eq 3"
elif [ $N -eq 5 ]; then
  echo "eq 5"
elif [ $N -eq 8 ]; then
  echo "eq 8"
else
  echo "no"
fi

如果第一个条件符合就不再向下匹配。

shell编程之if语句实战案例

需求:

1. 完成用户输入文件或者目录的自动复制,并可以实现用户指定复制目标位置。

2. 用户体验佳。

#!/bin/bash
read -p "pls enter a file you want to copy:" file
if [ -f $file -o -d $file ];then
        read -p "do you want to copy the $file?(y/n)" sure
     confirm=$(echo ${sure} | tr A-Z a-z)
if [ "$confirm" == "y" ];then read -p "where do you want to copy?" dire if [ -d $dire ];then cp -a $file $dire echo "the $file copied to $dire" else echo "the $dire is not exists" exit 1 fi elif [ "$confirm" == "n" ];then echo "bye" else echo "pls input y or n" fi else echo "the $file is not exists" fi

练习题1:尝试写一个shell简单的计算器,实现加减乘除。

请输入一个数字: 7

请输入运算符:+

请输入第二个数字:7

7+7=14

练习题2:输入一个用户,用脚本判断判断该用户是否存在。

for语句

格式:for name [ [ in [ word ... ] ] ; ] do list ; done
for 变量名 in 取值列表; do
  命令
done

或者

  for 变量名 in 取值列表

  do

  命令

  done

实例1:

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

# bash test.sh
1
2
3

实例2:计算100以内偶数和

#!/bin/bash
sum=0
for i in `seq 2 2 100`
do
        let sum+=$i
done
echo "$sum"

shell编程之for语句实战案例

需求:

1. 批量检查当前教室主机是否在线

#!/bin/bash
ip=192.168.7.
for i in {1..255}
do
    ping -c 1 -w 1 $ip$i &>/dev/null
    if [ $? -eq 0 ];then
        echo "$ip$i在线!"
    else
        echo "$ip$i不在线!"
    fi

done

 练习题1:计算100以内的奇数和

while语句

条件为真就进入死循环;条件为假就退出循环

格式:while list; do list; done
while 条件表达式; do
    命令
done

实例1:

#!/bin/bash
N=0
while [ $N -lt 5 ]; do
  let N++
  echo $N
done

# bash test.sh
1
2
3
4
5

当条件表达式为 false 时,终止循环。

实例2:条件表达式为 true,将会产生死循环

#!/bin/bash
while [ 1 -eq 1 ]; do
  echo "yes"
done

也可以条件表达式直接用 true:

#!/bin/bash
while true; do
  echo "yes"
done

死循环有什么作用那?

可以用来后台运行检测脚本,如下是是一个检测脑裂的脚本

我们只需要在命令行中输入 nohup bash naolie.sh & 即可在后台持续运行该脚本

例子1:检测脑裂

#!/bin/bash
while true
do
        ip=`ip a s eth0 | awk -F " +" 'NR==4{print $3}' | awk -F "/" '{print $1}' | awk -F "." '{print $4}'`1
        ping -c 3 -i 1 -W 1 10.220.5.166 &>/dev/null
        if [ $? -eq 0 ] && [ $ip = 1001 ];then
                echo "happed naolie"
        else
                echo "everything is ok"
        fi
done

例子2:检测终端数量

#!/bin/bash
while true
do
    num=`who | wc -l`
    echo "当前打开终端数量为:$num"
    sleep 5
done

要想使用 while 循环逐行读取 a.txt 文件,有三种方式:

方式 1:

#!/bin/bash
cat ./a.txt | while read LINE; do
  echo $LINE
done

方式2:

#!/bin/bash
while read LINE; do
  echo $LINE
done < ./a.txt

方式3:

exec < ./a.txt    # 读取文件作为标准输出
while read LINE; do
  echo $LINE
done

与 while 关联的还有一个 until 语句,它与 while 不同之处在于,是当条件表达式为 false 时才循环,实际使用中比较少,这里不再讲解。

#!/bin/bash
n=0
until [ $n -eq 5 ]
do
        let n++
        echo "$n"

done

break和continue语句

break 是终止循环。

continue 是跳出当前循环。

示例 1:在死循环中,满足条件终止循环

#!/bin/bash
N=0
while true; do
    let N++
        if [ $N -eq 5 ]; then
            break
        fi
    echo $N
done

# bash test.sh
1
2
3
4            

里面用了 if 判断,并用了 break 语句,它是跳出循环。与其关联的还有一个 continue 语句,它是跳出本次循环。

示例 2:举例子说明 continue 用法

#!/bin/bash
N=0
while [ $N -lt 5 ]; do
    let N++
        if [ $N -eq 3 ]; then
            continue
        fi
    echo $N
done

# bash test.sh
1
2
4    

当变量 N 等于 3 时,continue 跳过了本次循环,没有执行下面的 echo。

注意:continue 与 break 语句只能循环语句中使用。

case语句

case 语句一般用于选择性来执行对应部分块命令。

case 模式名    in
模式 1)
  命令
  ;;
模式 2)
  命令
  ;;
*)
  不符合以上模式执行的命令
esac

每个模式必须以右括号结束,命令结尾以双分号结束,最后一个模式不需要添加;;。

示例1:根据位置参数匹配不同的模式

#!/bin/bash
case $1 in
start)
  echo "start."
  ;;
stop)
  echo "stop."
  ;;
restart)
  echo "restart."
  ;;
*)
  echo "Usage: $0 {start|stop|restart}"
esac

# bash test.sh
Usage: test.sh {start|stop|restart}

# bash test.sh start
start.

# bash test.sh stop
stop.

# bash test.sh restart
restart.

实例2:

#!/bin/bash
case $1 in
[0-9])
  echo "match number."
  ;;
[a-z])
  echo "match letter."
  ;;
'-h'|'--help')
  echo "help"
  ;;
*)
  echo "Input error!"
  exit
esac

# bash test.sh 1
match number.

# bash test.sh a
match letter.

# bash test.sh -h
help

# bash test.sh --help
help

模式支持的正则有:*、?、[ ]、[.-.]、|。后面有章节单独讲解 Shell 正则表达式。

shell编程高级实战

实战1:写一个猜数字的小游戏

要求:

1. 猜对退出

2. 数字随机

3. 使用体验佳

#!/bin/bash
clear
num=`echo $RANDOM`
count=0
while true
do
        let count++
        read -p "pls enter a num you guess:" guessnum
        if [ $guessnum -lt $num ]; then
                echo "the num is so smaller!"
        elif [ $guessnum -gt $num ];then
                echo "the num is so bigger!"
        elif [ $guessnum -eq $num ];then
                echo "right!wonderful! "
                break
        else
                echo "good bye"
                exit
        fi
done
echo -e "\033[36myou guess $count times\033[0m" #-e允许对下面列出的加反斜线转义的字符进行解释.

实战2:检测当前教室在线IP地址

要求:

1.显示美观

#!/bin/bash
. /etc/init.d/functions
ip=172.20.10.
for i in {1..255}
do
        if ping -c 1 $ip$i &>/dev/null ;then
                echo -n "$ip$i"    #-n表示不输出行尾的换行符
                success
                echo ""
        else
                echo -n "$ip$i"
                failure
                echo ""
        fi
done

实战3:检查软件包是否安装

要求:

1.用户输入软件名即可进行查询

#!/bin/bash
read -p "pls enter a softname:" softname
if rpm -q $softname &>/dev/null ;then
        echo "the $softname is already installed"
else
        echo "the $softname" is not installed
fi
02-19 21:54