shell分支与循环

1. 条件选择

1.1 条件判断分支介绍

格式

if COMMANDS; then COMMANDS; [ elif COMMANDS; then COMMANDS; ]... [ else
COMMANDS; ] fi
1.1.1 单分支结构
if 判断条件
then
    条件为真的分支代码
fi

# 或者

if 判断条件;then
    条件为真的分支代码
fi
1.1.2 双分支结构
if 判断条件; then 
    条件为真的分支代码
else
    条件为假的分支代码
fi
1.1.3 多分支结构
if 判断条件1; then 
    条件1为真的分支代码
elif 判断条件2; then 
    条件2为真的分支代码
elif 判断条件3; then 
    条件3为真的分支代码
...
else
    以上条件都为假的分支代码
fi

说明:

  • 多个条件时,逐个条件进行判断,第一次遇为“真”条件时,执行其分支,而后结束整个if语句

  • if 语句可嵌套

1.2 条件判断 case 语句

格式

case WORD in [PATTERN [| PATTERN]...) COMMANDS ;;]... esac
case 变量引用 in 
PAT1)
    分支1
    ;;
PAT2)
    分支2
    ;;
PAT3)
    分支3
    ;;
easc

case支持glob风格的通配符

* 任意长度任意字符
? 任意单个字符
[] 指定范围内的任意单个字符 
| 或者,如: a|b

示例

[root@centos8 ~/script]#cat yesorno.sh
#!/bin/bash
#
read -p "Do you agree(yes/no)? " INPUT

INPUT=$(echo $INPUT| tr 'A-Z' 'a-z')

case $INPUT in
y|yes)
	echo "You input is YES"
	;;
n|no)
	echo "You input is NO"
	;;
*)
	echo "Input fales,please input yes or no!"
esac

[root@centos8 ~/script]#cat yesorno2.sh
#!/bin/bash
#
read -p "Do you agree(yes/no)? " INPUT
case $INPUT in
[yY]|[Yy][Ee][Ss])
	echo "You input is YES"
	;;
[Nn]|[Nn][Oo])
	echo "You input is NO"
	;;
*)
	echo "Input fales,please input yes or no!"
esac
[root@centos8 ~/script]#

示例

#!/bin/sh
while true
do
    echo "********************************"
    echo "Please select your operation:"
    echo " 1 Copy"
    echo " 2 Delete"
    echo " 3 Backup"
    echo " 4 Quit"
    echo "********************************"
    read op
case $op in
    1)
        echo "your selection is Copy"
        ;;
    2)
        echo "your selection is Delete"
        ;;
    3)
        echo "your selection is Backup"
        ;;
    4)
        echo "Exit ..."
        break
        ;;
    *)
        echo "invalide selection,please try again"
        continue
esac
done

加减乘除

#!/bin/sh
# "select" "case" Uasge
echo "a is 5, b is 3.Please select you method: "
a=5
b=3
select var in "a+b" "a-b" "a*b" "a/b"
do
    break
done
case $var in
    "a+b") echo 'a+b='`expr $a "+" $b`;;
    "a-b") echo 'a-b='`expr $a "-" $b`;;
    "a*b") echo 'a*b='`expr $a "*" $b`;;
    "a/b") echo 'a/b='`expr $a "/" $b`;;
    *) echo "input error..."
esac
sh select_case.sh

归档日志

cat archive_updateserver.sh 
#!/bin/bash
# Parameters
###################################
PREFIX="/search/odin/updateserver"
LOGNAME="ie_log access_log error_alert_log error_log stat_log update_log filter_log updateserver_log"
RESERVE_DAY="3"
###################################
DATE=`date -d "1 days ago" "+%Y%m%d"`
TODAY=`date "+%Y%m%d"`
DATE_0=`date -d"1 days ago" "+%F"`
OLDDATE=`date -d "${RESERVE_DAY} days ago" "+%Y%m%d"`
OLDDATE_0=`date -d "${RESERVE_DAY} days ago" "+%F"`
cd ${PREFIX}
mkdir -p ./log/history
for logtype in ${LOGNAME}
do
    mkdir -p ./log/history/${DATE}/${logtype} 
    case "$logtype" in
        "access_log")
            rm -f ./log/${logtype}/${logtype}_${DATE}.* &
            ;;
        "updateserver_log")
            mv -f ./log/updateserver_log/updateserver.log.${DATE}* ./log/history/${DATE}/${logtype}/
            mv -f ./log/updateserver_log/updateserver.log.wf.${DATE}* ./log/history/${DATE}/${logtype}/
            ;;
        *)
            mv -f ./log/${logtype}/${logtype}_${DATE}.* ./log/history/${DATE}/${logtype}/
            ;;
    esac
    case "$logtype" in
        "access_log")
            echo "ignore tar $logtype"
            ;;
        *)
            cd ./log/history/${DATE}/
            tar czf ${logtype}.tar.gz ${logtype}/  && rm -rf ${logtype} 
            cd ${PREFIX}
            ;;
    esac
done
rm -rf ./log/history/${OLDDATE}

2. 循环

将某代码段重复运行多次,通常有进入循环的条件和退出循环的条件

重复运行次数

  • 循环次数事先已知

  • 循环次数事先未知

常见的循环的命令:for, while, until

2.1 当型和直到型循环语法

2.1.1 while
while COMMANDS; do COMMANDS; done

while CONDITION; 
do 
    循环体
done

说明:

  • CONDITION:循环控制条件;进入循环之前,先做一次判断;每一次循环之后会再次做判断;条件为 “true”,则执行一次循环;直到条件测试状态为“false”终止循环,因此:CONDTION一般应该有循环控 制变量;而此变量的值会在循环体不断地被修正

  • 进入条件:CONDITION为 true

  • 退出条件:CONDITION为 false

无限循环

while true; do 
    循环体
done


while : ; do 
    循环体
done

总结:while循环特长是守护执行进程,频率小于1分钟

示例1:通过while循环竖向打印10,9,8 。。。1

#!/bin/bash
i=10
while ((i>0))       # 双小括号的用法
do
    echo $i
    ((i--))
done

#!/bin/bash
i=10
while [[ $i > 0 ]]  # 双中括号的用法,注意使用 $i 调用
do
    echo $i
    ((i-2))
done

示例2:计算 1+2+3+…+100 的综合和平均数

[@sjs_115_196 ~]# cat while.sh 
#!/bin/bash
sum=0
i=1
while [ $i -le 100 ]
do
    sum=$(($sum+$i))
    i=$(($i+1))
done
echo $sum
echo $(($sum/($i-1)))
[@sjs_115_196 ~]# sh while.sh 
5050
50
[@sjs_115_196 ~]#

示例

# 配置发邮件的邮箱
[root@centos8 ~]#cat .mailrc
set from=262410965@qq.com
set smtp=smtp.qq.com
set smtp-auth-user=262410965@qq.com
set smtp-auth-password=zrppnudhpwqncaec
set smtp-auth=login
set ssl-verify=ignore
[root@centos8 ~]#
[root@centos8 ~/script]#cat while_diskcheck.sh
#!/bin/bash
#
warning=80
while :;do
	diskwarning=$(df -h|awk '!/Filesystem/{split($5,arr,"%");if(arr[1] > $warning){print arr[1],$NF}}')
	echo -e "Disk will be full from $(hostname -I)\n$diskwarning"| mail -s 'disk warning' 262410965@qq.com
	sleep 10
done
[root@centos8 ~/script]#

示例:防止Dos攻击的脚本

cat check_link.sh
#!/bin/bash
#
WARNING=10
touch deny_hosts.txt
while true;do
    ss -nt | sed  -nr '1!s#.* ([0-9.]+):[0-9]+ *#\1#p'|sort |uniq -c|sort |
while read count ip;do
        if [ $count -gt $WARNING ];then
            echo $ip is deny
            grep -q "$ip" deny_hosts.txt || { echo $ip >> deny_hosts.txt;
iptables -A INPUT -s $ip -j REJECT; }
        fi 
    done
    sleep 10 
done
2.1.2 循环until

格式

until COMMANDS; do COMMANDS; done

until CONDITION; do 
    循环体
done

说明

  • 进入条件: CONDITION 为false

  • 退出条件: CONDITION 为true

[root@centos8 ~]#sum=0;i=1;until ((i>100));do let sum+=i;let i++;done;echo $sum
5050
[root@centos8 ~]#

无限循环

until false; do 
    循环体
done

2.2 for循环结构

# CentOS7的for帮助比CentOS8全面
[root@centos7 ~]# help for
for: for 名称 [in 词语 ... ] ; do 命令; done
    为列表中的每个成员执行命令。

    `for' 循环为列表中的每个成员执行一系列的命令。如果没有
    `in WORDS ...;'则假定使用 `in "$@"'。对于 WORDS 中的每
     个元素,NAME 被设定为该元素,并且执行 COMMANDS 命令。

    退出状态:
    返回最后执行的命令的状态。
for ((: for (( 表达式1; 表达式2; 表达式3 )); do 命令; done
    算术 for 循环。

    等价于
    	(( EXP1 ))
    	while (( EXP2 )); do
    		COMMANDS
    		(( EXP3 ))
    	done
    EXP1、EXP2 和 EXP3都是算术表达式。如果省略任何表达式,
    则等同于使用了估值为1的表达式。

    退出状态:
    返回最后执行的命令的状态。
[root@centos7 ~]#
2.2.1 格式1
for NAME [in WORDS ... ] ; do COMMANDS; done

#方式1
for 变量名 in 列表;do
    循环体
done

#方式2
for 变量名 in 列表 
do
    循环体
done
 

提示:在此结构中“in 变量取值列表”可省略,省略时,相当于in“ @ ” , 使 用 f o r i 就 相 当 于 使 用 f o r i i n " @”,使用for i就相当于使用for i in " @使fori使foriin"@"

执行机制:

  • 依次将列表中的元素赋值给“变量名”; 每次赋值后即执行一次循环体; 直到列表中的元素耗尽,循环 结束

  • 如果省略 [in WORDS … ] ,此时使用位置参量

for 循环列表生成方式:

  • 直接给出列表

  • 整数列表

{start..end}                 # 序列方式:for i in {1..5};do echo $i;done 

$(seq [start [step]] end)    # 输出奇数:for i in $(seq 1 2 10);do echo $i;done
  • 返回列表的命令
$(COMMAND)
  • 使用glob,如:*.sh

  • 变量引用,如: @ , @, @*,$#

示例1:自定义分隔符,使用完成后恢复为默认的分隔符

#!/bin/bash
var="hello,world,!,!,!"
oldIFS=$IFS
IFS=,
for item in $var
do
    echo $item
done
IFS=$oldIFS

示例2:100 以内奇数之和

[root@centos8 ~]#sum=0;for i in {1..100..2};do let sum+=i;done;echo sum=$sum
sum=2500
[root@centos8 ~]#seq -s+ 1 2 100 | bc
2500
[root@centos8 ~]#echo {1..100..2}|tr ' ' + | bc
2500
[root@centos8 ~]#sum=0;for i in $(seq 1 2 100);do let sum+=i;done;echo sum=$sum
sum=2500
[root@centos8 ~]#

示例3:计算1+2+3+…+100的综合和平均数

[@sjs_115_196 ~]# cat test.sh
#!/bin/bash
sum=0
n=0
for i in `seq 100`
do 
    sum=$(($sum+$i))
    n=$(($n+1))
done
echo "相加综合":$sum
echo "平均数":$(($sum/$n))
[@sjs_115_196 ~]# sh test.sh
相加总和:5050
平均数:50
[@sjs_115_196 ~]#


[root@centos8 ~]#seq -s+ 100 |bc
5050
[root@centos8 ~]#echo {1..100}|tr ' ' + | bc
5050
[root@centos8 ~]#seq 100 | paste -sd + | bc
5050
[root@centos8 ~]#

示例:批量创建10个系统账号并设置随机密码

cat for_user.sh
#!/bin/bash
#
for n in $(seq -w 10)
do
    id user${n} >/dev/null 2>&1 && echo $user is exist || { useradd user$n; echo user$n is created; }
    pass=$(cat /dev/urandom | tr -dc '[:alnum:]' |head -c12)
    echo "$pass" | passwd --stdin user${n} &>/dev/null
    echo -e "user:user${n} pass:${pass}" >> /tmp/useradd.log
   echo "user${n} is created"
done

非交互模式修改密码

echo "password" | passwd --stdin username
#
useradd -d /search/dev -m adpc; echo 'adpc2015' | passwd --stdin adpc
useradd -d /search/users/for_adr -m for_adr;echo 'for_adr2015' | passwd --stdin for_adr
useradd -d /search/users/for_add -m for_add;echo 'for_add2015' | passwd --stdin for_add
useradd -d /search/ADQuery -m op_biz;echo 'op_biz2015' | passwd --stdin op_biz
useradd -d /search/dev -m worker;echo 'apecblue' | passwd --stdin worker

示例:99乘法表

[@sjs_115_196 ~]# cat test.sh
#!/bin/bash
for i in `seq 9`
do
    for j in `seq 9`
    do
        [ $j -le $i ] && echo -n "$j x $i = $(($i*$j)) "   # -n:不换行
    done
    echo ""
done
[@sjs_115_196 ~]# sh test.sh
1 x 1 = 1 
1 x 2 = 2 2 x 2 = 4 
1 x 3 = 3 2 x 3 = 6 3 x 3 = 9 
1 x 4 = 4 2 x 4 = 8 3 x 4 = 12 4 x 4 = 16 
1 x 5 = 5 2 x 5 = 10 3 x 5 = 15 4 x 5 = 20 5 x 5 = 25 
1 x 6 = 6 2 x 6 = 12 3 x 6 = 18 4 x 6 = 24 5 x 6 = 30 6 x 6 = 36 
1 x 7 = 7 2 x 7 = 14 3 x 7 = 21 4 x 7 = 28 5 x 7 = 35 6 x 7 = 42 7 x 7 = 49 
1 x 8 = 8 2 x 8 = 16 3 x 8 = 24 4 x 8 = 32 5 x 8 = 40 6 x 8 = 48 7 x 8 = 56 8 x 8 = 64 
1 x 9 = 9 2 x 9 = 18 3 x 9 = 27 4 x 9 = 36 5 x 9 = 45 6 x 9 = 54 7 x 9 = 63 8 x 9 = 72 9 x 9 = 81 
[@sjs_115_196 ~]#

另外几种写法:

[root@centos8 ~]#cat for3.sh
#!/bin/bash
#
for j in $(seq 9)
do
	for i in $(seq $j)
	do
		echo -e "\E[1;$[RANDOM%7+31]m$i"x"$j=$[i*j]\E[0m\t\c"
	done
	echo
done
[root@centos8 ~]#bash for3.sh
1x1=1
1x2=2	2x2=4
1x3=3	2x3=6	3x3=9
1x4=4	2x4=8	3x4=12	4x4=16
1x5=5	2x5=10	3x5=15	4x5=20	5x5=25
1x6=6	2x6=12	3x6=18	4x6=24	5x6=30	6x6=36
1x7=7	2x7=14	3x7=21	4x7=28	5x7=35	6x7=42	7x7=49
1x8=8	2x8=16	3x8=24	4x8=32	5x8=40	6x8=48	7x8=56	8x8=64
1x9=9	2x9=18	3x9=27	4x9=36	5x9=45	6x9=54	7x9=63	8x9=72	9x9=81
[root@centos8 ~]#

# 语法1实现
for i in {1..9};do
    for j in `seq $i`;do
        echo -e "${j}x$i=$((j*i))\t\c"
    done
    echo
done

# 语法2实现 
for((i=1;i<10;i++));do
    for((j=1;j<=i;j++));do
        echo -e "${j}x$i=$((j*i))\t\c"
    done
    echo
done

# awk的写法:
awk 'BEGIN{for(i=1;i<=9;i++){for(j=1;j<=i;j++)printf j"x"i"="j*i"\t";print}}'
2.2.2 C 语言型 for 循环结构

双小括号方法,即((…))格式,也可以用于算术运算,双小括号方法也可以使bash Shell实现C语言风格 的变量操作

for ((: for (( exp1; exp2; exp3 )); do COMMANDS; done

for ((控制变量初始化;条件判断表达式;控制变量的修正表达式)) 
do
    循环体
done

说明:

  • 控制变量初始化:仅在运行到循环代码段时执行一次

  • 控制变量的修正表达式:每轮循环结束会先进行控制变量修正运算,而后再做条件判断

示例

[root@centos8 ~/script]#cat sum.sh
#!/bin/bash
#
for((sum=0,i=1;i<=100;i++))
do
	let sum+=i
done
echo sum=$sum

for((sum=0,i=1;i<=100;sum+=i,i++))
do
	true
done
echo sum=$sum

sum=0
for((i=1;i<=100;i++))
do
	((sum+=i))
done
echo sum=$sum
[root@centos8 ~/script]#bash sum.sh
sum=5050
sum=5050
sum=5050
[root@centos8 ~/script]#

示例:生成进度

[root@centos8 ~/script]#for ((i = 0; i <= 100; ++i)); do printf "\e[4D%3d%%" $i;sleep 0.1s; done
100%[root@centos8 ~/script]#

示例

[root@centos8 ~/script]#for((;;));do echo for;sleep 1;done
for
for
for
for
for
for
^C
[root@centos8 ~/script]#

示例:

failcount=0
for((i=1;i<=3;i++))
do
    wget -T 5 --tries=1 --spider http://${1} > /dev/null 2>&1
    [ $? -ne 0 ] && let failcount+=1;
done


if [ $failcount -gt 1 ];then
    retval=1
    now_time=`date +"$m-%d %H:%M:%S"`    
fi

2.3 break continue exit

break;continue;exit:一般用于循环结构中控制循环的走向:

2.3.1 循环控制语句 continue

continue [N]:N 表示退到第 N 层继续循环,如果省略 N 表示跳出本次循环,忽略本次循环的剩余代码,进入循环的下一个循环,最内层为第 1 层

格式

while CONDITION1; do
    CMD1
    ...
    if CONDITION2; then
        continue
    fi
    CMDn
    ...
done

示例:continue的用法,跳出本次循环

[@sjs_115_196 ~]# cat test.sh
#!/bin/bash
for ii in `seq 3`
do
    for i in `seq 3`
      do
        if [ $i -eq 2 ];then
          continue
        fi
        echo $i
    done
    echo "this is ii:$ii"
done
[@sjs_115_196 ~]# sh test.sh
1
3
this is ii:1
1
3
this is ii:2
1
3
this is ii:3
[@sjs_115_196 ~]#
2.3.2 循环控制语句 break

break [N]:N 表示跳出循环的层数,如果省略 N 表示跳出整个循环,最内层为第 1 层

格式

while CONDITION1; do
    CMD1
    ...
    if CONDITION2; then
        break
    fi
    CMDn
    ...
done

示例:break的用法,break只能用于循环,跳出整个(break所在的那层)循环

[@sjs_115_196 ~]# cat test.sh
#!/bin/bash
for ii in `seq 5`
do
    for i in `seq 5`
      do
        if [ $i -eq 3 ];then
          break
        fi
        echo $i
    done
    echo "this is ii:$ii"
done
[@sjs_115_196 ~]# sh test.sh
1
2
this is ii:1
1
2
this is ii:2
1
2
this is ii:3
1
2
this is ii:4
1
2
this is ii:5
[@sjs_115_196 ~]#
2.3.3 循环控制语句 exit

exit [N] : 退出当前 shell 程序,并返回 N,N 可以省略

示例

[@sjs_115_196 ~]# cat test.sh
#!/bin/bash
for((i=1;i<=5;i++))
do
    if [ "$i" -eq 3 ];then
    #    continue
    #    break
        exit 
    fi
    echo "$i"
done
[@sjs_115_196 ~]# sh test.sh
1
2
[@sjs_115_196 ~]# 

示例:exit的用法,退出当前shell程序

[@sjs_115_196 ~]# cat test.sh
#!/bin/bash
for ii in `seq 5`
do
    for i in `seq 5`
      do
        if [ $i -eq 3 ];then
            exit    
        fi
        echo $i
    done
    echo "this is ii:$ii"
done
[@sjs_115_196 ~]# sh test.sh
1
2
[@sjs_115_196 ~]#

示例:循环检查最近几分钟日志是否滚动

for((i=1;i<=15;i++))
do
    cmd="/usr/bin/find $log_dir -type f -mmin -$interval"
    ssh -oConnectTimeout=60 "${IP}" "${cmd}" < /dev/null > $check_temp
    filefound=`cat $check_temp | wc -l`
    rm -rf $check_temp
    if [ -z "$filefound" -o $filefound -eq 0 ]; then
        sleep 60
        continue
    else
        return 0
    fi
done
return 1

示例:检查web站点目录下所有文件是否被恶意篡改,如果有就打印改动的文件名(生产环境用MD5验证)

#!/bin/bash
for f in `ls *.log`;do wc -L $f;done > cc.txt
[ -f /etc/rc.d/init.d/functions ] && . /etc/rc.d/init.d/functions
for f in `ls *.log`
do
    if [ `cat $f|wc -L` -ne `grep $f c.txt |awk '{print $1}'` ];then
        action "$f" /bin/false
    else
        action "$f" /bin/true
    fi
done

find /etc/ -type f -name "*" -exec md5sum {} >/root/checkmd5.db \;
#!/bin/bash
check_dir=/etc
if [[ -e /root/checkmd5.db ]];then
    md5sum -c /root/checkmd5.db>/root/result.db 2>/dev/null
    egrep -i "FAILED" /root/result.db >/root/err.log
    if [[ ! -s /root/err.log ]];then
        mail -s "$(uname -n) $(date +%F) weberr" 12123@qq.com</root/err.log
    fi
fi

3. 循环控制 shift 命令

shift [n] 用于将参量列表 list 左移指定次数,缺省为左移一次。

参量列表 list 一旦被移动,最左端的那个参数就从列表中删除。while 循环遍历位置参量列表时,常用到 shift

[root@centos8 ~/script]#cat doit.sh
#!/bin/bash
#
while (( $# > 0 ))
do
	echo $*
	shift
done
[root@centos8 ~/script]#bash doit.sh a b c d
a b c d
b c d
c d
d
[root@centos8 ~/script]#

示例

[root@centos8 ~/script]#cat shift.sh
#!/bin/bash
#
until [ -z "$1" ]
do
	echo "$1"
	shift
done
[root@centos8 ~/script]#bash shift.sh a b c d
a
b
c
d
[root@centos8 ~/script]#

示例:用shift实现值的累加

cat test.sh
#!/bin/bash
if [ $# -le 0 ];then
	echo -e "\033[31mnot engouth paramters\033[0m"
	exit
fi
#用shift实现值的累加
sum=0
while [ $# -gt 0 ]
do
	sum=$(($sum+$1))
	shift
done
echo $sum

$ sh test.sh 1 2 3 4 5
15

4. while 特殊用法 while read

while 循环的特殊用法,遍历文件或文本的每一行

方式一:按行读入

exec<file
sum=0
while read line
do
    cmd
done

方式二:按行读入

cat ${FILE_PATH} | 
while read line
do
    cmd
done

方式三:

while read line 
do
    循环体
done < /PATH/FROM/SOMEFILE

说明:依次读取/PATH/FROM/SOMEFILE文件中的每一行,且将行赋值给变量line

示例

[root@centos8 ~]#echo xufengnian | read NAME;echo $NAME

[root@centos8 ~]#echo xufengnian | while read NAME;do echo $NAME;done
xufengnian
[root@centos8 ~]#echo xufengnian | { read NAME; echo $NAME; }
xufengnian
[root@centos8 ~]#echo xufengnian | ( read NAME; echo $NAME )
xufengnian
[root@centos8 ~]#echo xu feng nian | ( read X Y Z; echo $X $Y $Z )
xu feng nian
[root@centos8 ~]#echo xu feng nian | while read X Y Z; do echo $X $Y $Z;done
xu feng nian
[root@centos8 ~]#

示例

[root@centos8 ~]#cat while_read_check_dos.sh
#!/bin/bash
#
MAX=3
lastb | sed -rn '/ssh:/s@.* ([0-9.]{1,3}{3}[0-9]{1,3}) .*@\1@p'|sort |uniq -c | while read count ip ;do
    if [ $count -gt $MAX ];then
        iptables -A INPUT -s $ip -j REJECT
	fi
done
[root@centos8 ~]#

示例:查看/sbin/nologin的shell类型的用户名和UID

[root@centos8 ~]#cat while_read_passwd.sh
#!/bin/bash
#
while read line
do
	if [[ "$line" =~ /sbin/nologin$ ]];then
		echo $line | awk -F':' '{print $1,$3}'
	fi
done < /etc/passwd
[root@centos8 ~]#

5. 循环与菜单 select

格式

select NAME [in WORDS ... ;] do COMMANDS; done

select variable in list ;do 
    循环体命令
done

说明:

  • select 循环主要用于创建菜单,按数字顺序排列的菜单项显示在标准错误上,并显示 PS3 提示符,等待用户输入

  • 用户输入菜单列表中的某个数字,执行相应的命令

  • 用户输入被保存在内置变量 REPLY 中

  • select 是个无限循环,因此要用 break 命令退出循环,或用 exit 命令终止脚本。也可以按 ctrl+c 退出循环

  • select 经常和 case 联合使用

  • 与 for 循环类似,可以省略 in list,此时使用位置参量

示例

[root@centos8 ~/script]#cat select.sh
#!/bin/bash
#
sum=0
ps3="Your position is(1-6): "
select MENU in CEO CTO CFO CMO COO END;do
case $REPLY in
1)
	echo $MENU The salary is 100000
	let sum+=100000
	;;
2)
	echo $MENU The salary is 80000
	let sum+=80000
	;;
3)
	echo $MENU The salary is 70000
	let sum+=70000
	;;
4)
	echo $MENU The salary is 66800
         let sum+=66800
	;;
5)
	echo $MENU The salary is 66666
	let sum+=66666
	;;
6)
	echo "end"
	break
	;;
*)
	echo "Wrong input, please try again"
	;;
esac
done
echo "The total cost: $sum"
[root@centos8 ~/script]#bash select.sh
1) CEO
2) CTO
3) CFO
4) CMO
5) COO
6) END
#? 1
CEO The salary is 100000
#? 2
CTO The salary is 80000
#? 3
CFO The salary is 70000
#? 6
end
The total cost: 250000
[root@centos8 ~/script]#
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值