函数
函数(function),在很多情况下,我们需要多次处理重复的业务,或者复杂的业务时,可以将其单独封装成一个函数,这样既可以提高代码阅读性,也可以进行解耦,以及减少重复代码。
需要注意的是,shell脚本是由上到下,从左到右一次执行的,所以,函数一定要声明在调用之前。
函数中可以使用return
来显式地退出,后面可以接0-255范围内的整数,默认为0,代表正常退出,其余均为不正常退出。
函数的声明
[function] fnc_name(){
fnc_body
# do whatever you want here
}
函数的调用
# 直接写出函数名即可,不加括号,并且参数不是写在括号中,而是接在空格后,多个参数用空格分割
fnc_name param1 param2 param3 ... paramN
函数的内置变量
同shell script一样,函数也有很多内置变量,并且和shell script用法基本相同
变量 | 含义 |
---|---|
$# | 所传递的参数的总个数 |
$* | 以字符串的形式,显示所传递的所有参数 |
$$ | 显示当前进程的PID |
$@ | 如为加引号,则使用时与$*相同,但是使用时如果加了引号,则每个变量都会以引号的方式返回。 |
$? | 上一条命令的执行状态码,0为正常,其他为错误 |
这里写一个简单的例子,顺便演示一下$*与$@的区别
vim fnc_test.sh
#!/bin/bash
# Program:
# Program shows how to define and call a function with parameters
# and tell us the different between $* and $@
# History:
# yyyy/mm/dd Shuu First release
function fnc_a(){
echo "======> the variable '\$\*' without \"\" is like:"
for var in $*;
do
echo $var
done
echo "======> the variable '\$\@' without \"\" is like:"
for var in $@;
do
echo $var
done
}
# call the fnc_a and pass the parameters
fnc_a one two three four five six
function fnc_b(){
echo "======> the variable '\$\*' with the \"\" is like:"
for var in "$*";
do
echo $var
done
echo "======> the variable '\$\@' with the \"\" is like:"
for var in "$@";
do
echo $var
done
}
# call the fnc_b and pass the parameters
fnc_b one two three four five six
可以看见,当不括在双引号中时,两者没有区别,当放在双引号中时,"$*“会将所有参数当做一个字符串返回,中间用空格分割。”$@"则会将每个参数都用双引号括起来,而不是被串起来当做一个字符串。
变量
在bash shell中,变量的默认类型为字符串,除非显式地声明变量类型。
变量的声明------declare
在bash shell中,可以使用declare来显式地声明变量,并指定变量的类型。
注:在bash shell中,系统声明的变量一般为全大写字母,例如:PATH,PS1,ENV,LANG等等
所以,我们在脚本中声明的变量一般可以以非全大写的形式,这样方便于区分,如path,env,lang,lang_all等等。
declare [+/-] type var_name[=var_value]
# 其中,减号【-】用来指定变量的类型,而加号【+】用来取消变量的类型
e.g:
declare -i int_val=1
# 此外,如上所述,bash shell的变量默认类型为string,所以一般我们使用字符串变量时无需使用declare关键字
e.g:
str="A B C D"
type | 含义 |
---|---|
-a | array 数组 |
-i | integer 整数 |
-r | readonly 只读 |
-l | lower 赋值给该变量的字符串中的所有大写字母都会被变为小写字母 |
-u | upper 赋值给该变量的字符串中的所有小写字母都会被变为大写字母 |
变量的赋值与使用
# 变量的赋值方式
var_name=var_value
# 这里要注意的是,等号【=】前后不能有空格,也就是说,变量名,等号【=】,变量值一定要紧紧相连,如下图所示
# 变量的使用方式
$val_name
或
${val_name}
# 需要在变量之前加上$或者将变量包含在${}之中才可以,否则只会被当作普通的字符串,拿我们上面的变量a来演示:
# 但是,要注意的是,变量进行再赋值等操作时,则需要直接使用变量名,而不能加${}:
a="test"
变量的数学运算
数学运算符:+,-,*,/,%与其他大多数语言相同,分别代表,加,减,乘,除,取模(mod)
由于在bash shell中,变量的默认类型为string(除非显式地用declare声明),所以如果需要进行数学运算时,需要使用let
命令或将运算式写在$(( 运算式 ))中。
下面让我们一点点来验证
#!/bin/bash
# Program:
# to shows the basic math function in bash shell
# History:
# yyyy/mm/dd Shuu First release
length=123
width=456
area=length*width
echo ${area}
area=${length}*${width}
echo ${area}
发现,虽然我们赋值给的是数字,但是结果得到的仍然是字符串的形式,下面我们使用let的方式来尝试一下:
#!/bin/bash
# Program:
# to shows the basic math function in bash shell
# History:
# yyyy/mm/dd Shuu First release
length=123
width=456
#area=length*width
#echo ${area}
#area=${length}*${width}
#echo ${area}
let area=${length}*${length}
echo ${area}
echo $(( ${length} * ${width} / 123 ))
在这里,顺便提一下,在bash shell中产生随机数的方法:
==>RANDOM
变量
RANDOM变量的取值范围是0~32767之间的整数,但是这个范围有些大,一般情况下我们用到的大多只有3位数左右,
那如果我们想要选取0~10之间的随机数该怎么办呢?
#!/bin/bash
# Program:
# to generate the random number between 0 and 10 with the RANDOM variable
# History:
# yyyy/mm/dd Shuu First release
declare -a num_arr
declare -i size=0
while [ ${#num_arr[@]} -lt 11 ]
do
random_num=$(( ${RANDOM} * 10 / 32767 ))
flg="OK"
if [ ${size} -ge 1 ]; then
for idx in `seq 0 $(( ${size} -1 ))`
do
if [ ${num_arr[${idx}]} == ${random_num} ]; then
flg="NG"
fi
done
fi
if [ ${flg} == "OK" ];then
num_arr[${size}]=${random_num}
let size++
fi
done
echo ${num_arr[@]}
注:上面很多地方可以改写,如$(())和let两种方式并存等等,这里主要是为了演示,并起到练习的作用。
数组
数组可以存放多个值,下标也是从0开始,在bash shell中,数组内的元素可以是任意类型,但在bash shell中,仅支持一维数组。
另外,在bash shell中,数组可以不定义长度,直接使用。
数组的赋值方式
# 将值以空格分割,放在括号()之中
arr=(val1 val2 val3 val4 ....valN)
# 使用下标赋值
arr[0]=val1
arr[1]=val2
arr[2]=va3
数组的使用
数组的读取:
# 读取数组的方式:
echo ${arr[index]}
# 读取数组中所有元素:下面两种方式均可
echo ${arr[*]}
# 或
echo ${arr[@]}
数组长度的获取与数组的遍历:
# 数组长度的获取方式一般为:
${#arr[*]}
# 或
${#arr[@]}
具体演示:
#!/bin/bash
# Program:
# to show the basic use of the array in bash shell
# History:
# yyyy/mm/dd Shuu First release
declare -i int=1
str="abc"
declare -a arr
arr=(${int} ${str})
echo ${arr[@]}
arr[2]="The last element of the Array"
echo ${arr[*]}
for i in `seq 1 ${#arr[@]}`
do
idx=$((i - 1))
echo ${arr[${idx}]}
done