一、数组
bash
提供对于一维数组的支持,需要注意的是,它并不支持多维数组。通常情况下,数组的索引为一个整数,从0
开始计算。但是我们也可以使用字符串作为数组的索引,这样的数组被称为关联数组。
1.1 在 bash
中,变量可以理解为只有一个元素的索引数组:
shiyanlou@d03dd6e50718:~$ var1=Manchangdx # 定义变量
shiyanlou@d03dd6e50718:~$ echo $var1
Manchangdx
shiyanlou@d03dd6e50718:~$ echo ${var1[0]} # 查看数组的第一个元素
Manchangdx
shiyanlou@d03dd6e50718:~$ echo ${var1[1]}
shiyanlou@d03dd6e50718:~$
1.2 可以直接使用数字索引增加元素:
shiyanlou@d03dd6e50718:~$ var1[1]=hello
shiyanlou@d03dd6e50718:~$ var1[5]=world
shiyanlou@d03dd6e50718:~$ echo ${var1[1]}
hello
shiyanlou@d03dd6e50718:~$ echo ${var1[2]}
shiyanlou@d03dd6e50718:~$ echo ${var1[5]}
world
shiyanlou@d03dd6e50718:~$ echo $var1 # 数组变量的值为第一个元素
Manchangdx
shiyanlou@d03dd6e50718:~$ echo ${var1[*]} # 查看数组中的所有元素
Manchangdx hello world
shiyanlou@d03dd6e50718:~$
1.3 var=(value1 value2 value3)
的方式定义数组:
shiyanlou@d03dd6e50718:~$ var2=(a b c)
shiyanlou@d03dd6e50718:~$ echo $var2
a
shiyanlou@d03dd6e50718:~$ echo ${var2[0]}
a
shiyanlou@d03dd6e50718:~$ echo ${var2[1]}
b
shiyanlou@d03dd6e50718:~$ echo ${var2[2]}
c
shiyanlou@d03dd6e50718:~$ echo ${var2[3]}
shiyanlou@d03dd6e50718:~$
1.4 declare -A
声明关联数组:
shiyanlou@d03dd6e50718:~$ declare -A var3
shiyanlou@d03dd6e50718:~$ var3=([name]=James [age]=22 [addr]=Cav)
shiyanlou@d03dd6e50718:~$ echo $var3 # 关联数组没法打印
shiyanlou@d03dd6e50718:~$ echo ${var4[1]} # 也不能使用数字索引
shiyanlou@d03dd6e50718:~$ echo ${var3[name]}
James
shiyanlou@d03dd6e50718:~$ echo ${var3[*]}
James 22 Cav
shiyanlou@d03dd6e50718:~$ declare -A var4=([name]=Kobe [age]=33 [addr]=Tor)
shiyanlou@d03dd6e50718:~$ echo $var4
shiyanlou@d03dd6e50718:~$ echo ${var4[age]}
33
shiyanlou@d03dd6e50718:~$
1.5 数组的引用方式:
格式 | 含义 |
---|---|
${array_name[n]} | 查看指定索引的元素,n 为数组的索引 |
${array_name[*]} | 所有的数组元素的值 |
${array_name[@]} | 所有的数组元素的值 |
${!array_name[@]} | 所有的索引 |
${!array_name[*]} | 所有的索引 |
${array_name[*]:m} | 从索引m 开始,后面的所有元素 |
${array_name[*]:m:n} | 从索引 m 开始,后面的 n 个元素 |
${#array_name[*]} | 显示数组元素个数 |
1.6 删除:
shiyanlou@d03dd6e50718:~$ echo ${var4[*]}
Kobe 33 Tor
shiyanlou@d03dd6e50718:~$ echo ${!var4[*]}
name age addr
shiyanlou@d03dd6e50718:~$ unset var4[addr] # 删除一个元素
shiyanlou@d03dd6e50718:~$ echo ${var4[*]}
Kobe 33
shiyanlou@d03dd6e50718:~$ echo ${!var4[*]}
name age
shiyanlou@d03dd6e50718:~$ unset var4
shiyanlou@d03dd6e50718:~$ echo ${var4[*]} # 删除整个数组
shiyanlou@d03dd6e50718:~$
二、函数
2.1 定义
bash 也有自定义函数的功能,当脚本变得很大时,可将脚本文件中常用的功能写成函数,这样可以提高程序的复用性,更易维护。定义函数语法如下:
函数名() {
函数体
}
# 或者
function 函数名() {
函数体
}
# 或者
function 函数名 {
函数体
}
举个例子:
[shiyanlou@haha ~]$ nl test.sh
1 #!/bin/bash
2 func() {
3 echo $*
4 }
5 func $*
6 echo $*
[shiyanlou@haha ~]$ bash test.sh a hello world
a hello world
a hello world
2.2 变量作用域
bash 函数中变量的作用域与其它高级编程语言不同。如果我们在函数中有一行定义变量的语句,在我们调用函数后,该定义被执行,这时定义的变量并不属于函数内部的局部变量,在函数外部也可以使用。而定义属于函数内部的变量我们需要使用 local
命令:
[shiyanlou@haha ~]$ nl test.sh
1 #!/bin/bash
2 func() {
3 var1=shiyanlou
4 local var2=haha
5 }
6 func
7 echo $var1 $var2
[shiyanlou@haha ~]$ bash test.sh
shiyanlou
2.3 返回值
每一个脚本或者命令执行完成之后都会有一个退出的状态,系统中一般只会记录上一个指令执行之后的退出状态。和执行脚本一样,函数执行完成后也会有一个返回的状态值,默认为函数体中最后一行命令执行的状态,也可以显式地使用 return
语句给函数返回一个状态值,该语句会导致函数停止执行,并且将状态值返回给调用者,如果未提供该语句,则返回值是在该函数中执行的最后一个命令的退出状态。举例说明:
[shiyanlou@haha ~]$ nl test.sh
1 #!/bin/bash
2 func() {
3 echo start function
4 return 123
5 echo function end
6 }
7 func
8 echo "return: $?"
[shiyanlou@haha ~]$ bash test.sh
start function
return: 123
2.4 关于 bash 函数的几个小例子
2.4.1 获得命令行参数中的最大值:
[shiyanlou@haha ~]$ cat -n maxvalue.sh
1 max() {
2 while test $1 # 如果存在第一个参数,test 判断为真
3 do
4 if test $maxvalue; then
5 if test $1 -gt $maxvalue; then
6 maxvalue=$1
7 fi
8 else
9 maxvalue=$1
10 fi
11 shift # 函参整体左移一位,参数二挤掉参数一变成第一个参数,以此类推
12 done
13 return $maxvalue
14 }
15
16 max $*
17
18 echo Max value is $maxvalue
[shiyanlou@haha ~]$ bash maxvalue.sh 12 23 34 5 6
Max value is 34
2.4.2 调用另一个 bash 脚本:
[shiyanlou@haha ~]$ cat -n beidy.sh
1 #!/bin/bash
2
3 echo who you are: $USER
[shiyanlou@haha ~]$ cat -n dy.sh
1 #!/bin/bash
2
3 echo you locate $0
4
5 bash beidy.sh
6
7 echo first arg is $1
[shiyanlou@haha ~]$ bash dy.sh hello
you locate dy.sh
who you are: shiyanlou
first arg is hello
2.4.3 测试一组 URL 能否访问:
[shiyanlou@haha ~]$ cat -n test_url.sh
1 #!/bin/bash
2
3 URL_LIST=(
4 t.tt
5 https://www.shiyanlou.com
6 https://www.google.com
7 )
8
9 wait() {
10 echo -n 'wait 3 seconds' # -n 不换行
11 for ((i=0;i<3;i++))
12 do
13 echo -n '.'; sleep 1 # 程序挂起一秒钟
14 done
15 echo # 前面的 echo 都没换行,这里补一个换行符
16 }
17
18 check_url() {
19 wait
20 for ((i=0;i<${#URL_LIST[*]};i++))
21 do
22 # -o 将日志信息写入 /dev/null 空设备
23 # -T 超时时间设为 3 秒
24 # -t 设置重试次数为 1 次
25 # --spider 不下载任何文件
26 # > /dev/null 2>&1 将所有输出信息全扔到空设备
27 wget -o /dev/null -T 3 -t 1 \
28 --spider ${URL_LIST[$i]} > /dev/null 2>&1
29 if [ $? -eq 0 ]; then
30 echo "${URL_LIST[$i]} success"
31 else
32 echo "${URL_LIST[$i]} false"
33 fi
34 done
35 }
36
37 main() {
38 check_url
39 }
40
41 main
[shiyanlou@haha ~]$ bash test_url.sh
wait 3 seconds...
t.tt success
https://www.shiyanlou.com success
https://www.google.com false