shell编程 流程控制和数组

流程控制

本章则带领大家学习几个特殊的命令:break(循环控制)、continue(循环控制)、exit(退出脚本)、return(退出函数)

区别和对比

在上述命令中,break、continue在条件语句及循环语句(for、while、if等)中用于控制程序的走向;而exit用于终止所有语句并退出当前脚本。除此之外,exit还可以返回上一次程序或命令的执行状态给当前Shell;return类似于exit,只不过return仅用于在函数内部,如下图所示

命令说明
break n如果省略n,则表示跳出整个循环,n表示跳出的循环层数
continue n如果省略n,则表示跳过本次循环,忽略本次循环剩余代码,进入循环的下一次循环,n表示遇到第n层继续循环
exit n退出当前shell、n为上一次程序指向的状态返回值,n也可以省略,在下一个shell里面可以通过“$?”接收exit n 的n值
return n用于在函数里作为函数的返回值,判断函数执行是否正确。在下一个代码块里面可以通过“$?”接收return n 的n值

命令的基础示例

 下面是与break、continue、exit、return相关的示例

[root@oldchang ~]# cat test9-1.sh
#!/bin/bash
if [ $# -ne 1 ]; then    #<= 如果传参个数部位1,则打印下面的使用提示
    echo $"usage:$0 {break|continue|exit|return}"  #<== 分别传入4个命令作为参数
    exit 1               #<= 退出脚本
fi
function test(){
    for((i=0; i<5; i++));do
        if [ $i -eq 3 ];then
          $*;            #<= 这个地方的"$*" 就是接收函数以外的参数,是{break|continue|exit|return}其中一个
        fi
        echo $i
    done
    echo "I am in func." #<= 函数内循环外的输出提示
}
test $*                  #<= 这里的$*为参数的传参
func_ret=$?              #<= 接收并测试函数返回值
if [ `echo $* | grep return |wc -l` -eq 1 ];then  #<= 如果传参中含有return
   echo "return exit status: $func_ret"           #<= 则提示return退出状态
fi      
echo "ok"

 传入break的结果为

[root@oldchang ~]# sh test9-1.sh break
0
1
2
I am in func.
ok

可以看到,3以后的循环并未执行,这个是因为break及时跳出了循环,但是循环外的echo还在执行

 传入continue的结果为

[root@oldchang ~]# sh test9-1.sh continue
0
1
2
4
I am in func.
ok

可以看到,只有3循环没有执行,循环外的echo也在执行,说明到continue的时候,终止了本次循环,继续下一次循环,知道循环正常结束,然后执行后面的语句
 传入exit结果为

[root@oldchang ~]# sh test9-1.sh exit
0
1
2

当循环里面的if遇到exit之后,立刻退出了整个程序
 传入return的结果为

[root@oldchang ~]# sh test9-1.sh return
0
1
2
return exit status: 0
ok

可以看到,这次没有打印I am in func.这句话,证明在接收到return的时候,整个函数退出了,然后执行非函数的部分

数组

10.1 数组的分类
普通数组:只能使用整数作为索引
关联数组:可以只用字符串作为数组索引
10.2 普通数组
 数组名[索引]=变量值

[root@oldchang ~]# linux59[0]=jiaojiao
[root@oldchang ~]# linux59[1]=lili
[root@oldchang ~]# linux59[2]=xuxu
[root@oldchang ~]# echo ${linux59}       #<= 使用变量方式查看,其实查看的是数组第一个内容
jiaojiao
[root@oldchang ~]# echo ${linux59[0]}    #<= 查看数组第一个元素(0号)
jiaojiao
[root@oldchang ~]# echo ${linux59[1]}    #<= 查看数组第二个元素(1号)
lili
[root@oldchang ~]# echo ${linux59[*]}    #<= 查看数组的所有元素
jiaojiao lili xuxu
[root@oldchang ~]# echo ${!linux59[*]}   #<= 查看数组的所有索引
0 1 2
[root@oldchang ~]# echo ${#linux59[*]}   #<= 查看数组元素个数
3
[root@oldchang ~]# linux59[5]=oldchang   #<= 使用不连续索引赋值也可以
[root@oldchang ~]# echo ${linux59[*]}
jiaojiao lili xuxu oldchang
[root@oldchang ~]# unset linux59[5]      #<= 和变量类似,使用usset即可去掉数组中的的某些值
[root@oldchang ~]# echo ${linux59[*]}
jiaojiao lili xuxu
[root@oldchang ~]# linux59=(a b c d e f g) #<= 数组的批量赋值
[root@oldchang ~]# echo ${linux59[*]}
a b c d e f g

注:通过declare可以看到用户定义的数组

关联数组

 定义关联数组

# 首先定义一个关联数组
[root@oldchang ~]# declare -A array_1
# 关联数组赋值
[root@oldchang ~]# array_1[index1]=jiaojiao
[root@oldchang ~]# array_1[index2]=lili
[root@oldchang ~]# array_1[index3]=xixi
# 查看关联数组方式和查看普通数组方式相同,大家可以自己练习一下

数组自增

特殊情况下,可以用关联数组做计数

# 将array[m](关联数组)的值累加
# 先定义关联数组
[root@oldchang ~]# declare -A array_sex
# f解释为female,女性,即关联数组中女性的值自增1
[root@oldchang ~]# let array_sex[f]++
[root@oldchang ~]# let array_sex[f]++
[root@oldchang ~]# let array_sex[f]++
# f解释为male,男性,即关联数组中男性的值自增1
[root@oldchang ~]# let array_sex[m]++
[root@oldchang ~]# let array_sex[m]++
# 查看所有值
[root@oldchang ~]# echo ${array_sex[*]}
3 2
# 查看男性的个数
[root@oldchang ~]# echo ${array_sex[m]}
2
# 查看女性个数
[root@oldchang ~]# echo ${array_sex[f]}
3

练习:

1、  使用两种方法(包括一个数组方式),计算以下数据中性别出现的次数
zhangsan male
lisi female
wangwu male
lili male
xx female
mayun male
mahuateng male
wangjianlin male
cxk unknown

解决方法一

while read line;do
      a=`echo $line|awk '{print $2}'`
      if [ "$a" = 'male' ];then
         let m++
      fi
      if [ "$a" = "female" ];then
          let f++
      fi
done <$1
 echo "male为$m个"                       
 echo "female为$f个"

执行结果

[root@shell ~/html]# sh sex.sh user.txt
male为6个
female为2个

解决方法2

 declare -A array_sex
 while read line;do
       a=`echo $line|awk '{print $2}'`
       if [ "$a" = 'male' ];then
           let array_sex[m]++
       fi
       if [ "$a" = "female" ];then
           let array_sex[f]++
       fi
 done <$1
  echo "male为${array_sex[m]}个"
  echo "female为${array_sex[f]}个"       

执行结果

[root@shell ~/html]# sh sex2.sh user.txt
male为6个
female为2个

案例实操

1、已知下面的字符串是RANDOM随机数变量,经过md5sum之后,再截取一部分连续字符串的结果,请破解这些字符串在使用md5sum处理前对应的数字(使用数组与非数组两种方式)
21029299
00205d1c
a3da1677
1f6d12dd
890684ba
解决:

for ((a=0;a<=32767;a++));do
    echo  -en "$a\t" >>/tmp/md5.log                 
    echo  $a|md5sum|cut -c 1-8 >>/tmp/md5.log
done
while read line;do
    grep -w $line /tmp/md5.log
done <$1

RANDOM的取值范围是1-32756.先把1-32756的结果都做一个md5,然后截取前8位数。然后过滤以知道的MD5.

执行结果

[root@shell ~/html]# sh pass.sh md5.txt
25667   21029299
1346    00205d1c
25345   a3da1677
7041    1f6d12dd
10082   890684ba

2、学员信息系统,包括输入学员姓名,年龄,性别,输入指定个数之后,就可以进行查询

echo 0 >/tmp/userid.log
declare -A name
declare -A age
declare -A sex
function luru(){
#for ((i=0;i<=5;i++));do
i=`grep '[0-9]' /tmp/userid.log`
echo '欢迎进入学员信息录入系统'
read -p '请输入你的姓名: ' name
read -p '请输入你的年龄: ' age
read -p '请输入你的性别: ' sex
name[$i]=$name
age[$i]=$age
sex[$i]=$sex
echo '信息录入成功'
echo "$name的身份id为[$i]"
let i++ 
echo $i >/tmp/userid.log
#done

}
function chaxun(){
echo '欢迎进入学员信息查询系统'
read -p "请输入学员id: " a
echo  $a +  0|bc &>/dev/null
if [ "$?" -eq "0" ];then

echo ${name[$a]}  
echo ${age[$a]}
echo ${sex[$a]}
else
    echo "输入有误"
    exit
fi
}
while true;do
cat <<EOF
###########欢迎进入学员信息管理系统#############
             1.学员信息录入
             2.学员信息查询
             3.退出
EOF
read -p "请输入你要选择的功能: " x
case $x in
    1)
       luru        
        ;;
    2)
        chaxun
        ;;
    3)
        break
        ;;
    *)
      echo 输入有误
esac
done

执行结果

[root@shell /server/scripts]# sh xueyuan.sh                                                
###########欢迎进入学员信息管理系统#############
             1.学员信息录入
             2.学员信息查询
             3.退出
请输入你要选择的功能: 1
欢迎进入学员信息录入系统
请输入你的姓名: 葛邦风
请输入你的年龄: 32
请输入你的性别: 男
信息录入成功
葛邦风的身份id为[0]
###########欢迎进入学员信息管理系统#############
             1.学员信息录入
             2.学员信息查询
             3.退出
请输入你要选择的功能: 2
欢迎进入学员信息查询系统
请输入学员id: 0
葛邦风
32
男

trap信号说明

HUP(1) 挂起,通常因终端掉线或用户退出而引发
INT(2) 中断,通常因按下Ctrl+C组合键而引发
QUIT(3) 退出,通常因按下Ctrl+组合键而引发
ABRT(6) 中止,通常因为某些严重的执行错误引发
ALRM(14) 报警,通常用来处理超时
TERM(15) 终止,通常在系统关机时发送
SIGTSTP() 停止进程 终端来的停止信号
trap信号使用
trap “echo ‘想退出,没门’” INT HUP TSTP

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值