shell 脚本 函数和数组

目录

一:函数

1.1 什么是函数

1.2函数的语法

1.3函数的调用        

1.4 函数的返回值

1.5使用案例

方法1(无返回值无参数)

方法二 :使用函数传参(有参数无返回值)

方法三:使用函数返回值判断(有参数有返回值)

1.6函数库文件

1.7递归函数

示列:

二:数组

2.1定义数组

2.1.1示列:

方法一:

方法二:

方法三:

2.2数组的操作

2.2.1 获取所有元素

2.2.2 获取元素下标

2.2.3获取数组长度

2.2.4获取元素

2.2.5添加元素

2.2.6删除元素

2.2.7删除数组

2.2.8遍历数组

2.3数组示列

示列1:编写函数,实现打印绿色OK和红色FAILED 判断是否有参数,存在为Ok,不存在为FAILED

示列2:编写函数,实现判断是否无位置参数,如无参数,提示错误

 示列3:编写函数实现两个数字做为参数,返回最大值

 示例4:编写函数,实现两个整数位参数,计算加减乘除。

 示列5:将/etc/shadow文件的每一行作为元数赋值给数组

 示列6:使用关联数组统计文件/etc/passwd中用户使用的不同类型shell的数量

示列7:使用关联数组按扩展名统计指定目录中文件的数量 


一:函数

1.1 什么是函数

        所谓函数是将一组功能相对独立的代码集中起来,从而形成一个代码块,这个代码可以相对独立的完成某个功能,同时函数名与函数体形成映射,也就是说用户定义了函数后可以使用函数名来完成调用函数体,使开发更加的方便,代码更加简洁。

1.2函数的语法

function 函数名() {
 指令
 return
}
简化写法1:
function 函数名 {
 指令
 return
}
简化写法2:
函数名() {
 指令
 return
}

1.3函数的调用        

        function_name param1 param2 …
        在上面的语法中,function_name 表示函数名称,其后面跟的 param1 param2… 表示函数
的参数
1 )调用函数 : 直接执行函数名即可
        函数名
2)带参数的函数的执行方法:
        函数名  参数

1.4 函数的返回值

        首先用户可以用return的语句来返回某个数值  而这个数值的范围是0~255中的整数值,在函数中用户需要将返回的数据写入标准输出(stdout)通常这个操作一般使用echo命令来实现 然后将函数的执行结果赋值给一个变量

列如:

length()
{
 str=$1
 result=0
 if [ "$1" != "" ];then   #$1为函数第一个参数的值
 result=${#str}
 fi
 echo "$result"
}
len=$(length "abcd12")
echo "the string's length is $len"

执行结果:返回字符串的长度

1.5使用案例

        写一个脚本,判定192.168.33.120-192.168.33.130 之间的主机哪些在线。
要求:
        1、使用函数来实现一台主机的判定过程;
        2、在主程序中来调用此函数判定指定范围内的所有主机的在线情况。直接使用函数实现

方法1(无返回值无参数)

online()
{
 for i in {120..130};do
 if ping -c 1 192.168.33.$i &>/dev/null
 then
 echo "192.168.33.$i is up"
 else
 echo "192.168.33.$i is unknown"
 fi
 done
}
online

方法二 :使用函数传参(有参数无返回值)

online()
{
 if ping -c 1 $1 &>/dev/null 
 then
 echo "$1 is up"
 else
 echo "$1 is unknown"
 fi
}
for i in {120..130}
do
 online 192.168.33.$i
done

方法三:使用函数返回值判断(有参数有返回值)

online()
{
 if ping -c 1 $1 &>/dev/null
 then
 return 0
 else
 return 1
 fi
}
for i in {120..130}
do
 online 192.168.33.$i
 if [ $? -eq 0 ];then
 echo "192.168.33.$i is up"
 else
 echo "192.168.33.$i is unknown"
 fi
done

1.6函数库文件

1)函数库文件的定义:

        库文件的定义类似与脚本的编写 但是函数库文件只包括函数而脚本文件不但包括函数和变量的定义也包括代码(函数外可执行的代码,当脚本被载入时代码会被立即执行。

2)函数库的调用:

        当库文件定义好后,用户就可以在执行程序中载入库文件,并且调用其中的函数,载入命令为“.”

  语法为 . filename   

        其中filename为函数库的名称,库文件可以使用相对路径也可以使用绝对路径 ,另外 圆点和库文件之间有空格

1.7递归函数

        递归函数就是反复 的调用其自身,每调用一次就进入新一层的循环,即是调用者也是被调用者

示列:

        根据用户输入的数值计算阶乘

fact()
{
local n="$1"      #如果在函数内部没有使用local关键字进行修饰  那么函数的变量也会成为全局变量
if [ "$n" -eq 0 ]
then
 result=1
else
 let "m=n-1"
 fact "$m"
 let "result=$n * $?"
fi
 return $result
}
fact "$1"
echo "Factorial of $1 is $?"

二:数组

2.1定义数组

   方法一:用小括号将变量值括起来赋值给数组,每个变量之间用空格隔开

array = (value1 value2 value3 ... )

    方法二:用小括号将变量值括起来,同时采用键值对的形式赋值。当通过键值对定义数组时, 用户所提供的键值对中的元素索引不一定是连续的,可以任意指定要赋值的元素的索引。之所 以可以这样操作,是因为用户已经显式指定了索引,Shell就可以知道值和索引的对应关系。

array = ([0] = one [1] = two [2] = three ... [n] = valuen)

   方法三:分别定义数组变量的值

array[0]=a;array[1]=b;array[2]=c

   方法四:动态的定义变量,并使用命令的输出结果作为数组的内容

array=( 命令 )

  方法五:通过declare语句定义数组

declare -a array
定义关联数组:关联数组使用字符串作为下标,而不是整数,这样可以做到见名知意。
不同于普通数组,关联数组必须使用带有 -A 选项的 declare 命令创建

2.1.1示列:

方法一:

[root@kittod ~]# declare -A array
[root@kittod ~]# array[date1]=apple
[root@kittod ~]# array[date2]=banana
[root@kittod ~]# echo ${array[*]}
banana apple

方法二:

[root@kittod ~]# declare -A a
[root@kittod ~]# a=([index1]=tom [index2]=jack [index3]=alice)
[root@kittod ~]# echo ${a[@]}
tom jack alice

方法三:

[root@gdy ~]# declare -A arry
[root@gdy ~]# arry[0]=a;arry[1]=b;arry[2]=c
[root@gdy ~]# echo ${arry[@]}
c b a

2.2数组的操作

2.2.1 获取所有元素

[root@gdy ~]# echo ${array[*]}
banana orange apple
[root@gdy ~]# echo ${array[@]}
banana orange apple

2.2.2 获取元素下标

[root@gdy ~]# echo ${!array[@]}
date3 date2 date1

2.2.3获取数组长度

[root@gdy ~]# echo ${#array[@]}
3

2.2.4获取元素

[root@gdy ~]# echo ${array[date1]}
apple
[root@gdy ~]# echo ${array[date2]}
orange
[root@gdy ~]# echo ${array[date3]}
banana

2.2.5添加元素

[root@gdy ~]# array[date4]=watermelon
[root@gdy ~]# echo ${array[@]}
banana orange apple watermelon
[root@gdy ~]# 

2.2.6删除元素

[root@gdy ~]# echo ${array[@]}
banana orange apple watermelon
[root@gdy ~]# unset array[date1]
[root@gdy ~]# echo ${array[@]}
banana orange watermelon
[root@gdy ~]# 

2.2.7删除数组

[root@gdy ~]# unset array
[root@gdy ~]# echo ${array[@]}

[root@gdy ~]# 

2.2.8遍历数组

#方法 1:
#!/bin/bash
IP=(192.168.1.1 192.168.1.2 192.168.1.3)
for ((i=0;i<${#IP[*]};i++)); do
echo ${IP[$i]}
done
# bash test.sh
192.168.1.1
192.168.1.2
192.168.1.3
#方法 2:
#!/bin/bash
IP=(192.168.1.1 192.168.1.2 192.168.1.3)
for IP in ${IP[*]}; do
echo $IP
done

2.3数组示列

示列1:编写函数,实现打印绿色OK和红色FAILED 判断是否有参数,存在为Ok,不存在为FAILED

print ()
{
    if [ ! "$1" = "" ];
    then
        echo -e "有参数 :  \033[32m [OK] \033[0m"
    else
        echo -e "无参数 :  \033[31m [FALLED] \033[0m"
    fi
}
print $1

执行结果:

示列2:编写函数,实现判断是否无位置参数,如无参数,提示错误

num ()  
{
    if [ $# -eq 0 ];
    then
        echo "无位置参数 "
    else
        echo "位置参数为:$*" 
    fi
}
num $1 

执行结果:

 示列3:编写函数实现两个数字做为参数,返回最大值

compare ()
{
    if [ "$a" -gt "$b" ]
    then
        echo "参数1大于参数2 值为:$a"
    elif [ "$a" -lt "$b" ]
    then
        echo "参数2大于参数1 值为:$b"
    else 
        echo "相等 值为:$a"
    fi   
}         
read -p " please input two number " a b 
compare a b 

执行结果:

shell 脚本 函数和数组_第1张图片

 示例4:编写函数,实现两个整数位参数,计算加减乘除。

compute ()
{
    echo "$a+$b=`expr $a + $b `"
    echo "$a-$b=`expr $a - $b `"
    echo "$a*$b=`expr $a \* $b `"
    echo "$a/$b=`expr $a / $b `"
}
read -p " please input two number " a b
compute $1 $2

执行结果:

 示列5:/etc/shadow文件的每一行作为元数赋值给数组

func ()
{
    i=0
    while read line ;
    do
        arry[$i]=$line
        let i++
    done < /etc/shadow
}
func      
for i in ${arry[@]};
do        
    echo "$i" 
done    

执行结果:

shell 脚本 函数和数组_第2张图片

 示列6:使用关联数组统计文件/etc/passwd中用户使用的不同类型shell的数量

思路:利用重定向将文件/etc/passwd 重定向到函数中 再利用cut命令分割  将分割字符串作为关联数组的下标  通过while循环的遍历 实现下标的自加

declare -A count
func () 
{         
    while read line 
    do    
        type=`echo $line | cut -d: -f7`
        let count[$type]++
#        echo $type
    done < /etc/passwd
}     
func
for i in ${!count[*]}
do  
    echo "$i 的数量是:${count[$i]}" 
done

执行结果:

shell 脚本 函数和数组_第3张图片

示列7:使用关联数组按扩展名统计指定目录中文件的数量 

declare -A arry
read -p " 请输入目录的绝对路径" a
cd $a   
#for i in `ls`
#do          
#    if [ -f $i ];
#   then
#        echo $i >> /tmp/cishi.txt 
#    fi
#done
ls $1 | cut -d . -f2 >> /tmp/cishi.txt
while read line 
do  
        type=${line##*.}
        let arry[$type]++
done

执行结果:

shell 脚本 函数和数组_第4张图片

你可能感兴趣的:(服务器,linux)