Linux shell编程自动化运维 函数 shell循环的内置命令 详细解析

函数

概念

函数是一段完成特定功能的代码片段(块)
在shell中定义了函数,就可以使代码模块化,便于复用代码
注意函数必须先定义才可以使用。


重点

传参 $1,$2
局部变量 local
返回值 return 即 $?


定义函数

方法一:

函数名() {
函数要实现的功能代码
}


方法二:

function 函数名 {
函数要实现的功能代码
}


调用函数

语法

函数名
函数名  参数1   参数2


====================================================================
示例1:初识函数

需求

编写循环脚本,功能菜单
provide these tools:
show disk info(d)
show mem info(m)
show cpu info©
quit(q)


思路

1,编写菜单和判断
2,添加循环
3,添加函数


示例

#!/bin/bash
show_menu() {
cat << EOF
provide these tools:
 show disk info(d)
 show mem info(m)
 show cpu info(c)
 quit(q)
EOF
}

while :
do

show_menu
     read -p "Input choice: " choice
case $choice in
d)
echo "===========disk info=============="
     df -hT
;;
m)
echo "==========meme info==============="
     free -m
;;
c)
echo "==========cpu info================="
     uptime
;;
q)
      break
;;
*)
      show_menu
;;
esac
done

====================================================================
示例2:阶乘函数(传参)

需求

制作函数用于阶乘


思路

1 了解阶乘概念 12345=120
2 定义函数
3 引用函数


演示

#!/bin/bash
#定义函数名fun1
fun1() {
#定义阶乘元数
factorial=1
#使阶乘循环
for((i=1;i<=5;i++))
do
#阶乘公式
factorial=$[$factorial*$i]
done
#输出阶乘结果
echo “5的阶乘是:$factorial”
}
fun1
	for((i=1;i<=5;i++))
等同于
for i in ·seq 5·

优化
优化1:传参1,让函数能够自定义

#!/bin/bash
fun1() {
factorial=1
     for((i=1;i<=$1;i++))
do
     factorial=$[$factorial*$i]
done
     echo “$1的阶乘是:$factorial”
}

fun1  3

优化2:传参2, 由脚本外部传递参数

提示

函数传参能够在模块化的命令集中,添加自定义部分。参数应加在调用函数的后面。
shell脚本的参数与函数参数不同。是先将SHELL的参数传给函数,函数本身再转换到内部。

#!/bin/bash
fun1() {
factorial=1
for((i=1;i<=$1;i++))
do
factorial=$[$factorial*$i]
done
echo “$1的阶乘是:$factorial”
}

fun1 $1
fun1 $2
fun1 $3

测试:
[root@localhost ~]# bash cc.sh 3 5 10
       “3的阶乘是:6”
       “5的阶乘是:120”
       “10的阶乘是:3628800”

优化3,shell 的写法和其他运算表达式

#!/bin/bash
fun1() {
factorial=1
#for((i=1;i<=$1;i++))
for i in `seq $1`
do
#factorial=$[$factorial*$i]
#let factorial=$factorial*$i
let factorial*=$i
done
echo “$1的阶乘是:$factorial”
}

fun1  $1

====================================================================
示例3:函数传参, 数组传参
1,制作一个简单的阶乘脚本,通过数组给函数传参

#!/bin/bash
	#1 先定义一个数组
num=(1 2 3)
	#2 定义一个函数
array(){
factorial=1
for i in $*     #(重点2)
do
	#定义阶层的公式
factorial=$[factorial * $i]
done
echo $factorial
}
	#调用函数使用数组(重点1)
array ${num[*]}

测试成功
[root@localhost ~]# bash fun3.sh
6               

示例4:函数结果, 赋予数组

需求

用户获赠流量包(每人增加5G),结果运算

通过函数输出到数组

#!/bin/bash
num=(1 2 3)
array(){
#local定义变量仅在函数中有效。
local j
#设置循环的次数,等于索引总数。
   for i in  $*
do
#定义不同的值乘以5.注意调取值的时候使用的是索引。
   outarray[j++]=$[$i * 5]

done
#输出新的数组。
     echo "${outarray[*]}"
}
result=`array ${num[*]}`
     echo ${result[*]}

测试脚本成功
[root@localhost ~]# bash function_array.sh 
5 10 15

总结

函数不仅可以从中调取值,
还可以赋予数组值。


关于i++递增的问题

[root@localhost ~]# aaa[i++]=111
[root@localhost ~]# aaa[i++]=222
[root@localhost ~]# aaa[i++]=333
[root@localhost ~]# echo ${!aaa[@]}
  0 1 2
[root@localhost ~]# echo ${aaa[@]}
  111 222 333

[root@localhost ~]# ccc[++k]=111
[root@localhost ~]# ccc[++k]=222
[root@localhost ~]# ccc[++k]=333
[root@localhost ~]# echo ${!ccc[@]}
  1 2 3
[root@localhost ~]# echo ${ccc[@]}
  111 222 333
[root@localhost ~]# aaa[1]=3
[root@localhost ~]# echo ${aaa[@]}
  3
[root@localhost ~]# aaa[1]=$[3*5]
[root@localhost ~]# echo ${aaa[@]}
  15
[root@localhost ~]# aaa[i++]=20
[root@localhost ~]# aaa[i++]=25
[root@localhost ~]# aaa[i++]=30
[root@localhost ~]# echo ${aaa[@]}
  15 20 25 30

影响shell编程内部的命令

true
false
exit
break
continue
shift

true   真
false   假
shift   使位置参数向左移动,默认移动1位,可以使用shift 2
exit   退出整个程序
break   结束当前循环,或跳出本层循环
continue   忽略 // 跳过本次循环剩余的代码,直接进行下一次循环1

continue,break、shift

需求

通过循环脚本,输入如下效果
A123456789
B123456789

D123456789


环境示例
1.编写循环脚本

#!/bin/bash
for i in {A..D}
do
        echo $i
        for j in {1..9}
        do
                echo $j
        done
done

测试脚本1

 [root@localhost ~]# bash for1.sh
            A
            1
            2
            3
            4
            5
            6
            7
            8
            9
            B
          .......

因为默认echo 输出换行符,使用 -n 不输出
解决换行问题
脚本2

#!/bin/bash
for i in {A..D}
do
        echo -n $i
        for j in {1..9}
        do
                echo -n $j
        done
done

测试已优化的脚本2

 [root@localhost ~]# bash for1.sh
 
A123456789B123456789C123456789D123456789

外循环,添加一条空行语句

 #!/bin/bash
for i in {A..D}
do
        echo -n $i
        for j in {1..9}
        do
                echo -n $j
        done

        echo       //空行
done

测试最后优化的脚本

 [root@localhost ~]# bash for1.sh
     A123456789
     B123456789
     C123456789
     D123456789

总结
循环嵌套的规矩是:外部循环一次,内部消化全部



需求
跳出关于5的循环

使用 continue 跳过本次循环命令

 #!/bin/bash
for i in {A..D}
do
    echo -n $i
    for j in {1..9}
do
    if [ $j -eq 5 ];then        //判断是否为5
    continue              // 跳过本次循环
fi
     echo -n $j
done
        echo 
done

测试,
[root@localhost ~]# bash for1.sh
     A12346789
     B12346789C12346789
     D12346789

使用break测试

#!/bin/bash
for i in {A..D}
do
        echo -n $i
for j in {1..9}
do
      if [ $j -eq 5 ];then
          break 2
      fi
        echo -n $j
done
        echo 
done

测试脚本
[root@localhost ~]# bash for1.sh
    A1234

shift 移动参数

for 循环不定义循环范围,循环参数作为循环范围

#!/bin/bash
for i
do
        let sum+=$i
done
echo "sum : $sum"

测试
[root@localhost ~]# bash sum.sh 
sum : 
[root@localhost ~]# bash sum.sh 1
sum : 1
[root@localhost ~]# bash sum.sh 2
sum : 2
[root@localhost ~]# bash sum.sh 3
sum : 3
[root@localhost ~]# bash sum.sh 1 3
sum : 4

使用while循环,发现停不下来

#!/bin/bash
while [ $# -ne 0 ]
do
        let sum+=$1
        echo $sum
done
echo "sum : $sum"

测试
[root@localhost ~]# bash sum.sh 1 2
       根本停不下来。因为循环为真。

使用shift 移动参数的命令

#!/bin/bash
while [ $# -ne 0 ]
do
        let sum+=$1
        shift
done
echo "sum : $sum"

测试
[root@localhost ~]# bash sum.sh 1 2
sum : 3
[root@localhost ~]# bash sum.sh 1 2 3
sum : 6

shift总结

shift 1 使参数往左移一位,shift 2 左移2位

使用shift 创建用户,理解参数移位

#!/bin/bash
while [ $# -ne 0 ]
do
        useradd $1
        echo "$1 is created"
        shift
done

测试
[root@localhost ~]# bash shift_user.sh aa bb
   aa is created
   bb is created

你可能感兴趣的:(编程自动化运维,shell,shell,函数式编程,linux)