欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

马哥 31_01 _bash编程系列之数组 有大用

变量: 内存空间   bash shell 中所有的变量都是字符型

NUM=56



array: 数组

image.png

如何声明一个数组 

declare -a (-a 表示 array)

declare -a AA


赋值方法1:

AA[0]=jerry    #如果某一个值中间有空格的话 就用双引号引起来   AA[0]="jerry black"   

AA[1]=tom

AA[2]=wendy

AA[7]=natash       此时数组中有7个元素   AA[3] AA[4] AA[5] 均为空



赋值方法2:  用小括号,用空格隔开

AA=(jerry tom wendy natash)     #如果某一个值中间有空格的话 就用双引号引起来  AA=("jerry black" "tom obama" wendy natash)     

AA=([0]=jerry [1]=tom [2]=wendy [6]=natash)         #可以这里使用下标   此时数组中有7个元素   AA[3] AA[4] AA[5] 均为空

AA[3]=selina

AA[4]=nikita


引用数组变量 使用 ${AA[0]}  用美元符,用大括号,用下标


[root@mail ~]# mkdir scripts

[root@mail ~]# cd scripts

[root@mail scripts]# ls

[root@mail scripts]#




[root@mail scripts]# vim testarray.sh

#!/bin/bash

#

AA=([0]=jerry [1]=tom [6]=nikita)

echo ${AA[0]}


[root@mail scripts]# bash testarray.sh

jerry


[root@mail scripts]# vim testarray.sh

#!/bin/bash

#

AA=([0]=jerry [1]=tom [6]=nikita)

echo ${AA[0]}

echo ${AA[6]}

echo ${AA[2]}


[root@mail scripts]# bash testarray.sh

jerry

nikita


[root@mail scripts]#


[root@mail scripts]# vim testarray.sh

#!/bin/bash

#

AA=([0]=jerry [1]=tom [6]=nikita)


INDEX=$[$RANDOM%7]


echo ${AA[$INDEX]}



[root@mail scripts]# bash testarray.sh

nikita

[root@mail scripts]# bash testarray.sh

nikita

[root@mail scripts]# bash testarray.sh

tom

[root@mail scripts]# bash testarray.sh

jerry

[root@mail scripts]# bash testarray.sh

jerry

[root@mail scripts]# bash testarray.sh

nikita

[root@mail scripts]# bash testarray.sh


[root@mail scripts]# bash testarray.sh

jerry

[root@mail scripts]#


[root@mail scripts]# vim testarray.sh    #循环20次看看

#!/bin/bash

#

AA=([0]=jerry [1]=tom [6]=nikita)


for I in {1..20}; do

 INDEX=$[$RANDOM%7]

 echo ${AA[$INDEX]}

done

~



[root@mail scripts]# bash testarray.sh

jerry

nikita



nikita




nikita

nikita

jerry

jerry

tom



nikita





[root@mail scripts]#



${#array}  #  在数组名称前加井号 表示第0个元素的长度

${#array[0]}  # 最规范的做法,在数组名称前加井号 表示第0个元素的长度

${#array[1]}  # 最规范的做法,在数组名称前加井号 表示第1个元素的长度

${#array[*]}     或者 ${#array[@]}    # 数组中元素的个数 (元素的个数,不是下标的个数,而是有值的,值不为空的个数)



${aa[*]}  或者${aa[@]}     表示数组的所有值


[root@ha1 keepalived]# aa=(AA BB CC DD)

You have new mail in /var/spool/mail/root

[root@ha1 keepalived]# echo ${aa[*]}  

AA BB CC DD

[root@ha1 keepalived]# echo ${aa[@]}

AA BB CC DD


[root@ha1 keepalived]#





[root@mail scripts]# vim testarray.sh

#!/bin/bash

#

AA=([0]=jerry [1]=tom [6]=nikita)

echo ${#AA}


[root@mail scripts]# bash testarray.sh

5

[root@mail scripts]#

[root@mail scripts]# vim testarray.sh

#!/bin/bash

#

AA=([0]=jerry [1]=tom [6]=nikita)

echo ${#AA}

echo ${#AA[0]}

echo ${#AA[1]}


[root@mail scripts]# bash testarray.sh

5

5

3

[root@mail scripts]#


[root@mail scripts]# vim testarray.sh

#!/bin/bash

#

AA=([0]=jerry [1]=tom [6]=nikita)

echo ${#AA}

echo ${#AA[0]}

echo ${#AA[1]}


echo ${#AA[*]}

echo ${#AA[@]}

~



[root@mail scripts]# bash testarray.sh

5

5

3

3

3

[root@mail scripts]#



[root@mail scripts]# vim testarray.sh

#!/bin/bash

#

AA=([0]=jerry [1]=tom [6]=nikita)

AA[3]=natasha

echo ${#AA}

echo ${#AA[0]}

echo ${#AA[1]}


echo ${#AA[*]}

echo ${#AA[@]}



[root@mail scripts]# bash testarray.sh

5

5

3

4

4

[root@mail scripts]#


写一个脚本:

随机从同学们中选择一位回答问题


写一个脚本:

找出一组数据中的最大数,这组数据用数组保存


写一个脚本:

随机从同学们中选择5位回答问题 (5个人不能相同)


取最大值



[root@mail scripts]# vim findmax.sh   #取最大值

#!/bin/bash

#

ARRAY=(34 45 75 13 97 43 98 53 57 20)

declare -i MAX=${ARRAY[0]}

INDEX=$[${#ARRAY[*]}-1]

for I in `seq 1 $INDEX`; do

  if [ $MAX -lt ${ARRAY[$I]} ]; then

     MAX=${ARRAY[$I]}

  fi

done


echo $MAX




[root@mail scripts]# bash -n findmax.sh  #没有语法错误

[root@mail scripts]#

[root@mail scripts]# bash findmax.sh

98

[root@mail scripts]#


[root@mail scripts]# cp findmax.sh 2findmax.sh


随机生成10个数,再输出最大的数

[root@mail scripts]# vim 2findmax.sh

#!/bin/bash

#

for I in {0..9}; do

  ARRAY[$I]=$RANDOM

  echo  -n "${ARRAY[$I]}  "

done


echo


declare -i MAX=${ARRAY[0]}

INDEX=$[${#ARRAY[*]}-1]

for I in `seq 1 $INDEX`; do

  if [ $MAX -lt ${ARRAY[$I]} ]; then

     MAX=${ARRAY[$I]}

  fi

done


echo $MAX



[root@mail scripts]# bash 2findmax.sh

7351  20122  8217  5758  23427  30555  3148  6035  10841  18150

30555

[root@mail scripts]#

[root@mail scripts]# bash 2findmax.sh

32289  24264  2196  14052  880  25756  19045  22648  11606  26601

32289

[root@mail scripts]#

[root@mail scripts]# vim 2findmax.sh

#!/bin/bash

#

for I in {0..9}; do

  ARRAY[$I]=$RANDOM

  echo  -n "${ARRAY[$I]}  "

  sleep 1        # 每生成一个随机数的话就停1秒钟

done


echo


declare -i MAX=${ARRAY[0]}

INDEX=$[${#ARRAY[*]}-1]

for I in `seq 1 $INDEX`; do

  if [ $MAX -lt ${ARRAY[$I]} ]; then

     MAX=${ARRAY[$I]}

  fi

done


echo $MAX


image.png



生成一个数组,

1,数组元素个数是 1-39 个 (交互式命令行指定) 

        read 

2,数组元素不能相同

3,显示此数组各元素的值

[root@mail scripts]# vim createarray.sh

#!/bin/bash

#

read -p "The element numbers: " ELENUM


for I in `seq 0 $[$ELENUM-1]` ; do

  ARRAY[$I]=$RANDOM

  echo "${ARRAY[$I]}"

done


[root@mail scripts]# bash -n createarray.sh      # bash -n 检查shell脚本

[root@mail scripts]#


[root@mail scripts]# bash createarray.sh

The element numbers: 4

1367

11060

16707

7907

[root@mail scripts]#


[root@mail scripts]# bash createarray.sh

The element numbers: 6

2909

29306

27079

27750

16236

359

[root@mail scripts]#




[root@mail scripts]# vim createarray.sh   # 数组里生成的几个值 ,设置成不能有相同的

#!/bin/bash

#

read -p "The element numbers[1-39]: " ELENUM

declare -a ARRAY


function COMELE {

  for I in `seq 0 $[${#ARRAY[@]}-1]`; do

    if [ $1 -eq ${ARRAY[$I]} ]; then

        return 1

    fi

  done;


  return 0

}


for I in `seq 0 $[$ELENUM-1]` ; do

  while true; do

     ELEMENT=$RANDOM

     COMELE $ELEMENT

     if [ $? -eq 0 ]; then

       break;

     fi

  done

  ARRAY[$I]=$ELEMENT

  echo "${ARRAY[$I]}"

done


[root@mail scripts]# bash -n createarray.sh

[root@mail scripts]#


[root@mail scripts]# bash createarray.sh

The element numbers[1-39]: 3

16321

31705

13388

[root@mail scripts]#



[root@mail scripts]# bash createarray.sh

The element numbers[1-39]: 4

20667

13681

32178

1863

[root@mail scripts]#


[root@mail scripts]# vim createarray.sh

#!/bin/bash

#

read -p "The element numbers[1-39]: " ELENUM

declare -a ARRAY


function COMELE {

  for I in `seq 0 $[${#ARRAY[@]}-1]`; do

    if [ $1 -eq ${ARRAY[$I]} ]; then

        return 1

    fi

  done;


  return 0

}


for I in `seq 0 $[$ELENUM-1]` ; do

  while true; do

     ELEMENT=$[$RANDOM%40]   # 对 40取余的话 ,有可能值就有碰到相同的

     COMELE $ELEMENT

     if [ $? -eq 0 ]; then

       break;

     fi

  done

  ARRAY[$I]=$ELEMENT

  echo "${ARRAY[$I]}"

done




[root@mail scripts]# bash createarray.sh  #此时碰巧看到相同的,不应该啊

The element numbers[1-39]: 6

17

2

21

14

30

17

[root@mail scripts]#



[root@mail scripts]# bash -x createarray.sh

+ read -p 'The element numbers[1-39]: ' ELENUM

The element numbers[1-39]: 4

+ declare -a ARRAY

++ seq 0 3

+ for I in '`seq 0 $[$ELENUM-1]`'

+ true

+ ELEMENT=20

+ COMELE 20

++ seq 0 -1

+ return 0

+ '[' 0 -eq 0 ']'

+ break

+ ARRAY[$I]=20

+ echo 20

20

+ for I in '`seq 0 $[$ELENUM-1]`'

+ true

+ ELEMENT=22

+ COMELE 22

++ seq 0 0

+ for I in '`seq 0 $[${#ARRAY[@]}-1]`'

+ '[' 22 -eq 20 ']'

+ return 0

+ '[' 0 -eq 0 ']'

+ break

+ ARRAY[$I]=22

+ echo 22

22

+ for I in '`seq 0 $[$ELENUM-1]`'

+ true

+ ELEMENT=10

+ COMELE 10

++ seq 0 0

+ for I in '`seq 0 $[${#ARRAY[@]}-1]`'

+ '[' 10 -eq 22 ']'

+ return 0

+ '[' 0 -eq 0 ']'

+ break

+ ARRAY[$I]=10

+ echo 10

10

+ for I in '`seq 0 $[$ELENUM-1]`'

+ true

+ ELEMENT=20

+ COMELE 20

++ seq 0 0

+ for I in '`seq 0 $[${#ARRAY[@]}-1]`'

+ '[' 20 -eq 10 ']'

+ return 0

+ '[' 0 -eq 0 ']'

+ break

+ ARRAY[$I]=20

+ echo 20

20

[root@mail scripts]#


[root@mail scripts]# vim createarray.sh

#!/bin/bash

#

read -p "The element numbers[1-39]: " ELENUM

declare -a ARRAY


function COMELE {

  for J in `seq 0 $[${#ARRAY[@]}-1]`; do    # 把这里的I改成J,或者 I 声明成局部变量  local I ,应该就看不到重复的

    if [ $1 -eq ${ARRAY[$J]} ]; then

        return 1

    fi

  done;


  return 0

}


for I in `seq 0 $[$ELENUM-1]` ; do

  while true; do

     ELEMENT=$[$RANDOM%40]

     COMELE $ELEMENT

     if [ $? -eq 0 ]; then

       break;

     fi

  done

  ARRAY[$I]=$ELEMENT

  echo "${ARRAY[$I]}"

done



[root@mail scripts]# bash createarray.sh    # 此时看不到重复的

The element numbers[1-39]: 6

37

31

32

4

29

21

[root@mail scripts]# bash createarray.sh  # 此时看不到重复的

The element numbers[1-39]: 30

36

39

7

22

11

28

31

3

27

23

35

5

8

25

17

6

19

13

34

38

12

29

30

0

32

14

2

37

20

4

[root@mail scripts]#



trap 信号捕捉,在脚本中捕捉信号,并且可以实现特定处理

trap '' SIGNAL     (two adjacent apostrophes) disables SIGNAL for the remainder of the script

        trap:是捕捉命令

        '':表示捕捉后如何处理

        SIGNAL:表示捕捉到的信号

当我们定义了捕捉信号后,会取消到原来的信号捕捉定义,比如(ctrl+c 本来是中断退出的,此时就退出不了了)


trap '处理动作' 信号 



trap SIGNAL restores the functioning of SIGNAL once more 




    1: SIGHUP    可以捕捉

    2: SIGINT      可以捕捉 (int interrupt?) (ctrl+c发送的信号)

    3:

    4:

    5:

    6:

    7:

    8:

    9: SIGKILL          # 这个信号没法捕捉,如果捕捉到,任何人杀死不了你了

    15: SIGTERM     #  这个信号没法捕捉

    18: SIGCONT     #  可以捕捉 (cont continue ?)

    19: SIGSTOP      #  可以捕捉


[root@mail scripts]# vim 2findmax.sh

#!/bin/bash

#

trap 'echo "No quit..."' INT          # 信号写成INT也行 ,这一行表示 有人按 ctrl+c的时候,显示 No quit...

for I in {0..9}; do

  ARRAY[$I]=$RANDOM

  echo  -n "${ARRAY[$I]}  "

  sleep 1

done


echo


declare -i MAX=${ARRAY[0]}

INDEX=$[${#ARRAY[*]}-1]

for I in `seq 1 $INDEX`; do

  if [ $MAX -lt ${ARRAY[$I]} ]; then

     MAX=${ARRAY[$I]}

  fi

done


echo $MAX




[root@mail scripts]# bash 2findmax.sh        # 按住 ctrl+c 就不会中断执行了,就输出了 No quit...

17642  33  28606  23221  23684  No quit...

29254  23990  14111  23948  No quit...

24071

29254

[root@mail scripts]#


有时脚本 创建的许多文件,,生成的许多变量,,用户执行脚本后, 再按ctrl+c ,我们就能够 使用 trap 删除创建的文件,删除创建的变量



[root@mail scripts]# vim traptest.sh

#!/bin/bash

#

mkdir -p /var/tmp/test

while true; do

  touch /var/tmp/test/file-`date +%F-%H-%M-%S`   

             # %F     full date; same as %Y-%m-%d

             # %H     hour (00..23)

             # %M     minute (00..59)

             # %S     second (00..60)

  sleep 2

done


[root@mail scripts]# bash traptest.sh        # 按住 ctrl+c中止


[root@mail scripts]#


[root@mail scripts]# ls /var/tmp/test/            # 可以看到文件

file-2020-09-02-09-12-58  file-2020-09-02-09-13-00

[root@mail scripts]#


[root@mail scripts]# vim traptest.sh

#!/bin/bash

#

trap 'rm -Rf /var/tmp/test;echo "clean..."' INT   # 修改这里,当收到中断信号时,会删除本bash创建的文件

#这里用分号隔开的两个命令,还可以用多个命令的

mkdir -p /var/tmp/test

while true; do

  touch /var/tmp/test/file-`date +%F-%H-%M-%S`

  sleep 2

done



[root@mail scripts]# bash traptest.sh   # ctrl+c 取消不了了

clean...

touch: 无法触碰 “/var/tmp/test/file-2020-09-02-09-17-29”: 没有那个文件或目录

touch: 无法触碰 “/var/tmp/test/file-2020-09-02-09-17-31”: 没有那个文件或目录

clean...

touch: 无法触碰 “/var/tmp/test/file-2020-09-02-09-17-32”: 没有那个文件或目录

clean...

touch: 无法触碰 “/var/tmp/test/file-2020-09-02-09-17-34”: 没有那个文件或目录

touch: 无法触碰 “/var/tmp/test/file-2020-09-02-09-17-36”: 没有那个文件或目录




[1]+  Stopped                 bash traptest.sh   # 用 ctrl+z (应该是在后台运行)

[root@mail scripts]# kill 1%   # 再用1%来杀死这个进程

-bash: kill: 1%: arguments must be process or job IDs

[root@mail scripts]#



[root@mail scripts]# vim traptest.sh

#!/bin/bash

#

trap 'rm -Rf /var/tmp/test; echo "clean..."; exit 5 ' INT   # 所以我们还要使用 exit 5 来退出脚本 

mkdir -p /var/tmp/test

while true; do

  touch /var/tmp/test/file-`date +%F-%H-%M-%S`

  sleep 2

done


[root@mail scripts]# bash traptest.sh  # 此时按住 ctrl+c 可以正常退出了

clean...

[root@mail scripts]#



 trap 的处理逻辑可以定义成一个函数

[root@mail scripts]# vim traptest.sh

#!/bin/bash

#

CLEANUP() {

  rm -rf /var/tmp/test

  echo "Cleanup..."

}

trap 'CLEANUP;exit 5 ' INT

mkdir -p /var/tmp/test

while true; do

  touch /var/tmp/test/file-`date +%F-%H-%M-%S`

  sleep 2

done



[root@mail scripts]# bash traptest.sh   # 此时按住 ctrl+c 同样可以正常退出了

Cleanup...

[root@mail scripts]#


[root@mail scripts]# ls /var/tmp        # test 目录不存在

[root@mail scripts]#




普通分类: