第五章 函数
1,shell不能对编写的程序进行编译,而是在每次从磁盘加载这些程序时才能解释。对与这个问题我们用到shell函数,shell把函数放在内存中,每当需要执行时就不用再从磁盘读入,不用消耗大量时间来解释
2,shell分为内置命令,外部命令及特殊命令
1,函数概念
1,函数是由若干条shell命令组成的语句块,实现代码重用和模块化程序。它不是一个单独的进程,不能单独运行。它是shell程序的一部分。
2,shell函数和shell程序的区别:shell程序在子shell中运行,而shell函数在当前shell中运行,因此在当前shell中,函数可以钓鱼shell进行修改。
2,函数语法
#格式:
函数名(){
函数要实现的功能代码
}
或者:
funtion 函数名{
函数要实现的功能代码
}
#关键字funtion表示定义一个函数,可以省略。
3,函数调用
函数只有被调用才会执行,调用指定的函数名,函数名出现的地方,会被自动替换为函数代码。
函数的传参介绍
#基本语法:
函数名
#带参数语法:
函数名 参数1 参数2
shell的位置参数:(可以作为函数的参数来使用)
- 当n<10,用$n表示
- 当>=10,用${}表示
函数的返回值介绍
1,用$?返回一个状态码
2,用return关键字返回一个整数,作用是退出函数
3,用echo变量,返回一个字符串或其他类型
4,函数的应用实战
脚本中调用函数
函数必须在使用前需要被先定义。在脚本中使用函数时,必须在脚本开始前定义函数,调用函数仅使用函数名即可。
#阶乘脚本
[root@localhost script]# cat jc.sh
#!/bin/bash
jc(){ #定义函数为jc
jc=1
#判断i是否小于等于5,如果小于5就执行循环,完成了函数的定义
for((i=1;i<=5;i++))
do
jc=$[$jc * $i]
done
echo "5的阶乘是:$jc"
}
jc #调用函数,不需要带小括号
[root@localhost script]# chmod a+x jc.sh
函数的返回值
函数有两种返回值,分别为执行结果的返回值和退出状态码。函数执行结果的返回值使用echo等命令输出,它是函数体中调用命令的输出结果。函数的退出状态码取决于函数中执行的最后一条命令的退出状态码。
#自定义退出状态码的语句:
return 从函数中返回,用最后状态码命令绝对返回值
return 0 无错误返回
return 1~255 有错误返回
函数中的关键字return可以放到函数体的任意位置,通常用于返回某些值。Shell 在执行到return之后,就停止往下执行,返回到主程序的调用行。return 的返回
值只能是0~255的一个整数,返回值将保存到变量“$?” 中。
#函数的返回值return脚本
[root@localhost script]# cat return.sh
#!/bin/bash
rt(){
read -p "enter num:" num
return $[2*$num]
}
rt
echo "rt return value:$?"
[root@localhost script]# chmod a+x return.sh
#执行结果
[root@localhost script]# sh return.sh
enter num:3
rt return value:6
[root@localhost script]# sh return.sh
enter num:128
rt return value:0
#Shell的返回值最多为255,所以报错。
函数的位置参数
调用函数时,可以向其传递参数,在函数体内部通过$n的形式来获取参数的值。
[root@localhost script]# cat wz.sh
#!/bin/bash
if [ $# -ne 3 ]
echo ""usage:`basename $0` par1 par2 par3 #脚本的参数
exit
fi
wz(){
echo "$(($1*$2*$3))" #函数的参数
}
result=`wz $1 $2 $3` #这个本来就是的位置参数,但与函数的位置参数重合啦
echo “result is:$result”
函数数组变量的传参
[root@localhost script]# cat sz.sh
#!/bin/bash
num=(1 2 3 4 5)
cz(){
local jc=1
for i in $*
do
jc=$[jc*$i]
done
echo "$jc"
}
cz ${num[*]} #数组所有元数值
[root@localhost script]# chmod a+x sz.sh
函数的返回输出数组变量
[root@localhost script]# cat fhsz.sh
#!/usr/bin/bash
num1=(1 2 3)
num2=(2 3 4)
array(){
echo -e "all the parameters: $* \n"
local newarray=($*)
local i
for((i=0;i<$#;i++))
do
newarray[$i]=$(( newarray[$i] * 5 )) #根据数组的索引定义数组的值
done
echo "the new array is : ${newarray[*]}" #显示数组所有的元素
}
result=`array ${num1[*]}` #将num数组的值赋给result
echo ${result[*]}
result=`array ${num2[*]}` #将num2数组的值赋给result
echo ${result[*]}
5,内置命令和外部命令的区别
1,内部命令是shell程序的一部分。这些命令由解释器识别并在shell程序内部完成,通常在系统加载时就被加载并驻留在系统内存中。这些命令是写在bash源码里面的,执行速度比外部命令快,因为shell在解释内部命令时不需要创建子进程
**2,外部命令是写入中的实用程序。**系统加载时,它并不随系统一起被加载到内存中,**只有在需要是才被调用。**外部命令的实体并不在shell中,但其命令执行过程是由shell程序控制的。**shell程序可以管理外部命令执行的路径查找,加载和存放。**可以通过 echo $PATH命令查看外部的存储路径。
#用type命令可以分辨内部命令和外部命令
[root@localhost ~]# type cd
cd is a shell builtin
[root@localhost ~]# type mkdir
mkdir is /usr/bin/mkdir
3,两者最大的区别就是性能
6,内置命令
循环结构中break,continue,returnexit命令
1,break命令使用场景主要是Switch语句和循环语句
2,continue命令并没有真正退出循环,只是结束本次循环的执行。
3,return命令退出该函数的执行,退出到函数的调用处;如果在main()函数碰到return命令,则结束整个程序的运行。
4,exit和return最大的区别在于,**调用exit命令将结束当前进程,同时删除子进程所占用的内存空间,把返回信息传递给父进程。**当exit命令中的参数为0时,表示正常退出。
break,continue,exit命令执行流程图
break命令和continue命令案例实战
[root@localhost script]# cat continue.sh
#!/bin/bash
#最外层的for循环打印ABCD
for i in {A..D}
do
echo -n $i #-n显示不换行
for j in {1..9} #内循环打印1~9数字
do
if [ $j -eq 5 ];then #判断j是否等于5,如果等于5则跳出本次循环,开始下一轮循环
continue
fi
echo -n $j
done
echo #打印换行
done
[root@localhost script]# cat break.sh
#!/bin/bash
#最外层的for循环打印ABCD
for i in {A..D}
do
echo -n $i #-n显示不换行
for j in {1..9} #内循环打印1~9数字
do
if [ $j -eq 5 ];then #判断j是否等于5,如果等于5则跳出本次循环,开始下一轮循环
break
fi
echo -n $j
done
echo #打印换行
done
shift命令
1,对于位置参数或命令行参数来说,其个数必须是确定的;当shell程序不知道其个数时,可以把所有参数赋值给变量$*。
2,shift n表示把第n+1个参数移到第1个参数,即命令结束后 1 的值等于 1的值等于 1的值等于n+1的值,而命令执行前的前面n个参数不能被再次引用。
3,shift命令用于参数的移动(左移),通常用于在不知道传入参数个数的情况下依次遍历每个参数然后进行相应处理**(常见于Linux中各种程序的启动脚本)。**
#shell内置命令shift的用法脚本
[root@localhost scripts]# cat shift.sh
#!/bin/bash
while [ $# -ne 0 ]
do
useradd $1
echo "$1 is created"
shift
done
[root@localhost scripts]# chmod a+x shift.sh
[root@localhost scripts]# ./shift.sh y55 c77 i88
y55 is created
c77 is created
i88 is created
#shift命令每执行一次,变量的个数($#)减一,而变量值提前一位。