shell编程(三)

13  数组

          数组有两种:关联数据      索引数组

           # 索引数组使用从 0 开始的整数下标,下标必须是非负的整数
          # 关联数组使用字符串作为下标

          # 可以使用 declare -a 数组名 来声明索引数组
          # 必须使用 declare -A 数组名 来声明关联数组

 13.1  数组创建

                arr[0]=1

             13.12   # 按指定的下标,因此下标可以不连续,可以不按由小到大的顺序
                 arr4=([0]="aaa" [3]="bbb" [2]="ccc")  

                13.13 # 下标是默认从 0 开始的连续下标
                  arr5=("111" "222" "333" "444")   

              13.2 数组引用

                ${arr[0]}

              13.21 # 有指定下标和未指定下标混合使用时,--------------------- -------------------属于数组引用
                    # 从前往后,没有指定下标的默认从 0 下标开始,有指定下标的元素,
                    # 其后紧跟的未指定下标的元素,其下标递增,下标有重复的,
                   # 以最后出现的为准

 

         13.22 # 关于索引数组的负数下标:                              ------------------------   属于数组引用        
                   # 如果下标为负,则表示从数组的最后元素开始倒数
                  # -1 表示最大下标的元素,-2 表示倒数第 2 个元素,依此类推

         13.23# # 下标为 * 或 @ 时,表示数组的全部元素      -----------------------------  属于数组引用                
                     # 其中,* 表示以 "值1 值2 ..." 形式
                     # @ 表示以 "值1" "值2" ... 形式

                 57 arr=("aaaaa" "bbb" "ccc")
                 58 
                 59 for a  in "${arr[@]}";do
                 60         echo $a
                 61 done

 13.3

         # 求数组元素字符串长度:${#数组名[下标]}
             echo "\${#arr5[0]}=${#arr5[0]}"
             echo "\${#arr5}=${#arr5}"

          # 求数组长度:${#数组名[*或@]}
          # 如果索引数组中跳过了一些元素,则不计算长度
               echo "\${#arr5[*]}=${#arr5[*]}"
               echo "\${#arr4[@]}=${#arr4[@]}"   # [2] 元素跳过了,因此长度少 1

13.4

          # 由数组的下标可以产生一组值:${!数组名[*或@]}
         # [*] 产生的值是整个由 "" 括住的,形如:"值1 值2 ..."
         # [@] 产生的值每个值由一对 "" 括住,形如:"值1" "值2" ...
            echo "\${!arr5[*]}=${!arr5[*]}"
            echo "\${!arr5[@]}=${!arr5[@]}"
            echo "\${!arr4[*]}=${!arr4[*]}"
            echo "\${!arr4[@]}=${!arr4[@]}"

 

13.5

           # 取消数组元素:unset 数组名[下标]
            unset arr4[2]   # 取消下标为 2 的元素
            unset arr4[-1]   # 取消最后一个元素
            echo "\${#arr4[*]}=${#arr4[*]}"

            # 取消整个数组:unset 数组名  或  unset 数组名[*或@]
          unset arr5
          echo "\${#arr5[*]}=${#arr5[*]}"
          unset arr4[*]
          echo "\${#arr4[*]}=${#arr4[*]}"

               

14  函数       没有参数($1  $2),没有返回值(返回值可以通过三种方式得到)

            # shell 函数定义的格式:

            # name () compound-command [redirection]
            # function name [()] compound-command [redirection]

             # 没有返回值类型
             # 没有形参列表 

              # 使用 return 返回值,取值范围 0 - 255 之间
              # 如果超这个范围,只取最低字节(无符号值)

              # 使用全局变量带回值

               # 通过 $1 $2 ... 传递参数

------------------------------------------------------------------------------

            使用返回值

func1 ()
{
    echo "func1 ()"
    # 返回值 1
    return 1
#    return 257   # 257-256=1
}

func1
echo \$?=$?   # 打印 func1 函数调用的返回值

------------------------------------------------------------------------------------------

使用全局变量

result=0
myadd ()
{
    if (($# != 2)); then 
        echo "用法:$0 <num1> <num2>"
        return 1
    fi
    # 使用 $1 $2 ... 传递参数
    # 使用 全局变量 result 得到返回值
    # 因此必须在调用此函数结束后,立即检查 result 的值
    let result=$1+$2
}

//----------------------------------------------------------------------

通过第三个参数返回

# 将前两个参数相减,结果存入第 3 个参数
mysub ()
{
    if (($# != 3)); then 
        echo "用法:$0 <num1> <num2> <reference>"
        return 1
    fi
# -n 选项声明 tmp 为第 3 个参数的引用
# tmp 因为是在函数内部使用的变量,因此它是函数的局部变量
# 也可以使用 local 显式声明一个局部变量
    declare -n tmp=$3
    let tmp=$1-$2
}

# 调用时第 3 个参数为 r,则可以通过 r 带回返回值
mysub $num2 $num1 r
echo "$num2 - $num1 = $r"

---------------------------------------------------------------------------------------

# 如果是组合命令,则可以不使用 {}
# 组合命令如下:
# 1. (list)
# 2. { list; }
# 3. ((expression))
# 4. [[ expression ]]
# 5. for name [ [ in [ word ... ] ] ; ] do list ; done
# 6. for (( expr1 ; expr2 ; expr3 )) ; do list ; done
# 7. select name [ in word ] ; do list ; done
# 8. case word in [ [(] pattern [ | pattern ] ... ) list ;; ] ... esac
# 9. if list; then list; [ elif list; then list; ] ... [ else list; ] fi
# 10. while list-1; do list-2; done
# 11. until list-1; do list-2; done

# for in 循环就是一个组合命令
test () for v in 123 456; do echo $v; done

# 调用 test
test

----------------------------------------------------------------------------------

# 此脚本中要引用 funcs.sh 脚本中定义的一组函数,
# 必须 source funcs.sh 脚本
source ./funcs.sh           ####脚本引用

 

14   read  命令的使用

        read   a  b  c

         echo "$a  $b  $c"

         read  -p "请输入三个参数" a   b  c

          echo "$a  $b  $c"

          # 可以从管道中读取变量
          #ls ../ | while read file; do echo "$file"; done
          ls -i ../ | while read inode file; do echo "$inode-$file"; done

  15  select 命令

         # select 命令用 word ... 列表构建出一个菜单,供用户选择,
        # 每选择一个序号,就将这个序号对应的 word 赋值给 name,
         # 并且执行一次 list

          # select name [ in word ] ; do list ; done

  select a  in aa bb cc ee ;do
         echo $a
 done

运行上面三条语句,得到

1)aa

2) bb

3)cc

4)dd

可以通得输入1 2 3 4 得到输出aa bb cc dd .但 这个是死循环,所以得有个break; 跳出语句,见下

----------------------------------------------------------------------选择一个后退出

select week in Monday Tuesday Wednesday Thursday Friday Saturday Sunday;
do
    if [ -z "$week" ]; then
        echo "选择错误!请重新选择!"
    else
        break
    fi
done

echo "你选择了 $week"

---------------------------------------------------------------------------------------------------

 

16  脚本调试

# trap 命令用于捕获指定的信号并执行预定义的命令。

# 其基本的语法是:   trap 'command' signal

# command 就是要执行的命令,可以是自定义的函数。
# 也就是说 command 是用来处理 signal 信号的命令。

# signal  是要捕捉的信号
# signal 可以是 Linux 系统预定义的信号(kill -l 命令可以查看)
#  1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
# 6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1
# 11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM
# 16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
# 21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
# 26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR
# 31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
# 38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
# 43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
# 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
# 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
# 58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
# 63) SIGRTMAX-1  64) SIGRTMAX

# signal 还可以是 shell 内部自定义的信号(伪信号):
# EXIT  从一个函数中退出或整个脚本执行完毕
# ERR   当一条命令返回非零状态时(代表命令执行不成功)
# DEBUG 脚本中每一条命令执行之前 

 

从上面可以看出,  trap   命令要求两个参数

               'command'             可以是一个命令,  也可以是一个函数

                signal                    信号

 73 handle_exit ()
 74 {
 75    echo rvc  a signal
 76 }
 77 trap 'handle_exit'  EXIT

----------------------------运行上面,可以在shell结束后打印  rvc a signal


 79 handle_err ()
 80 {
 81    echo "this is a err"
 82 }
 83 trap 'handle_err' ERR
 84 
 85 aaaa
----------------------------------------------------在aaaa 处出错,  可以接收到 this is err

handler_debug ()
{
    echo "$1 行:收到 DEBUG 信号, \$i=$2"
}

# 捕捉 DEBUG 信号
trap 'handler_debug $LINENO $i' DEBUG

for ((i=0;i<3;i++)); do
    echo "\$i=$i"
done

----------------------------------------------------------------第一条语句,就一个handler_debug ()函数

 

         

 

 

 

      

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值