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“$@”,使用for i就相当于使用for i in "$@"
执行机制:
-
依次将列表中的元素赋值给“变量名”; 每次赋值后即执行一次循环体; 直到列表中的元素耗尽,循环 结束
-
如果省略 [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]#