shell 函数
传参 $1,$2
变量 local 如果想让变量只在函数内部使用,则使用local 变量名将变量做成局部变量即可
返回值return $?
======================================================
函数的功能
完成特定功能的代码片段(块)
在shell中定义函数可以使用代码模块化,便于复用代码
函数必须先定义才可以使用
1.定义函数
方法1:
函数名(){undefined
函数要实现的功能代码
}
方法2:
function 函数名 {undefined
函数要实现的功能代码
}
函数的调用方法:
函数名称 参数1 参数2
调用函数时可以传递参数,函数中使用$1、$2来传递参数
如果函数在另一个文件中存放,则在使用脚本前先执行该文件source f1.sh
注意:
1.函数接收位置参数:$1 $2 3... 3...3...n
2.函数接收数组变量: $* 或 $@
3.函数将接收到的所有参数赋给数组 newarray=($@)
4.函数中使用的参数个数 $#
1.1定义一个函数以及去调用
#!/bin/bahs factorial(){ factorial=1 for ((i=1;i<=10;i++)) do factorial=$[$factorial * $i] done echo "10的阶乘是:$factorial" } factorial
解释:第三行:#设置积乘的值为1,因为0的话就乱套了,0乘任何数都得0
第四行:#c语言的风格,定义i=1,当i小于等于10的时候,i的值就加1,先运算,运算完成后,i的值才会加1
第六行:#factorial 变量不是第三行的那个变量而是新定义的变量,变量名不建议重复以及不建议和命令同名,但是在这里变量不会像命令那样去执行,因此可以使用同名的变量名,[ [[factorial]中的factorial是同一行的变量名作为此变量,例如第一次循环factorial就等于1 12,第二次factorial就是2 23,第三次factorial就是6 64, 第四次factorial就是24 245…依次递增…
1.2使用变量进行函数传参
#!/bin/bash factorial(){ factorial=1 for i in $(seq $num) do factorial=$[$factorial * $i] done echo "$num 的阶乘是:$factorial" } num=5 factorial
解释:这里定义变量传参,在运行函数前,先定义好传参所用的变量
1.3使用函数位置变量进行传参
function factorial { factorial=1 for ((i=1;i<=$1;i++)) do factorial=$[$factorial * $i] done echo "$1 的阶乘是:$factorial" } factorial 10
解释:这里直接使用函数位置变量,即在执行factorial函数后面加上参数即可传递
第三行:#这里的$1是函数中的位置变量,与shell中的位置变量$1没有任何关系,即使在这里定义$1,执行脚本时./factorial 10也会>报错,因为shell中的位置变量$1不会传参到函数中的$1,如果函数需要传参则在执行函数时在后面加上参数即可,例如factorial 10这样就会被传到函数中
1.4使用shell位置变量向函数位置变量传参
执行方式./factorial 10 20
function factorial { factorial=1 for ((i=1;i<=$1;i++)) do factorial=$[$factorial * $i] done echo "$1 的阶乘是:$factorial" } factorial $1 factorial $2 factorial $3
解释:第九行:#这种函数后面加上shell位置变量就可以在脚本名后面加上参数./factorial 10这样的方法进行执行,这里的$1,$2,$3都会作为函数的第一个位置变量$1传回到函数中
第十行:#虽然这里是$2但是对于函数来说却是第一个参数,就会被传参到函数中的$1位置变量中
第十一行:#虽然这里是$3但是对于函数来说却是第一个参数,就会被传参到函数中的$1位置变量中
2.使用return命令来退出函数并返回特定的退出码
函数既然有位置参数那么也会有返回值,也是$?
函数的返回值是函数最后一条命令执行的结果,非0都是代表函数中最后一条命令执行失败
函数的状态返回码可以自己定义,但是不能超过255,一般利用return来返回函数的状态码
自定义函数状态返回码:return $[2*100]或者直接写一个值,return 3 函数的返回码最高值为255,不能超过255
return后面只能跟一个值,不能跟表达式,而这个值必须是小于等于255的值
2.1return实现函数的返回码
#!/bin/bash #----------------------利用return实现函数状态返回值--------------------- fun1() { read -p "enter number: " number return $[2*$number] #将运算的值作为状态返回结果 } fun1 echo "fun2 return value: $?" #$?的返回值是函数中最后一条命令的返回结果,如果使用了return则返回return的值
2.2return实现函数的返回码—固定值
#!/bin/bash fun1() { echo "return 3" return 3 echo "why" } fun1
2.3.如果函数的返回码要求大于255的实现方式
可以使用echo自定义的状态码,然后将函数的输出结果保存到每个变量中
#!/bin/bash fun2() { read -p "enter numbers: " num echo $[$num *2] } result=$(fun2) echo "fun2 return value: $result"
3.函数传参位置参数
$1对应函数中的$1,$2对应函数中的$2,$3对应函数中的$3
#!/bin/bash if [ $# -ne 3 ];then echo "usage: $(basename $0) par1 par2 par3" exit fi fun3() { echo $(($1*$2*$3)) } result=`fun3 $1 $2 $3` echo "$result"
4.函数传参 数组变量
#!/bin/bash num=(1 2 3) num1=(5 2 3) array() { local factorial=1 for i in $@ #这里可以使用$@或者$*,使用$*的时候不能加双引号 do factorial=$[$factorial * $i] done echo "$factorial" } array ${num[@]} #这里展开就是array 1 2 3所有在函数中可用使用$@或者$*来取所有参数 array ${num1[@]}
5.数组输入,数组输出
#!/bin/bash num=(10 20 30) fun(){ echo "all parmarent: $@" local newarray=($@) local i= local outarray= for ((i=0;i<$#;i++)) do outarray[$i]=$(( ${newarray[$i]} * 5 )) done echo "${outarray[@]}" } result=`fun ${num[@]}` echo "${result[@]}" array4() { echo "all parmaent: $@" local newarray1=($@) local i= local outarray= for i in {0..2} do outarray1[$i]=$[ ${newarray1[$i]} * 5 ] done echo "${outarray1[@]}" } array4 ${num1[@]} 两者输出一致 解释: local newarray=($@) #因为执行函数时是array3 ${num[@]}也就是array3 1 2 3 4,在这里呢使用$@取得所有参数放进newarray中作为新的数组 local i= #将i的值设置为空 for ((i=0;i<$#;i++)) #因为普通数组的索引从0开始,因此这里只有四个参数,i=0,i<$#也就是i=0,i<4只取0-3也就满足了元数个数 outarray[$i]=$(( ${newarray[$i]} * 5 )) #这里定义了一个outarray的函数,[$i]是索引的名称,${newarray[$i]} * 5是newarray数组中索引名称和outarray>数组中索引名称一致时*5,第一次循环就是outarray[0]=${newarray[0]} * 5,第二次循环就是utarray[1]=${newarray[1]} * 5 for i in {0..2} #这里不能使用$@因为$@是元数值,如果使用了$@那么在下面i就是10 20 30 因为没有这个索引位所以会报错
7.数组输入,数组输出
跟6的区别在于不再将所有参数保存到新的数组中
#!/bin/bash num=(10 20 30) fun() { local i=() local j= local outarray= for i do outarray[j++]=$[$i*5] done echo "${outarray[@]}" } fun ${num[@]} 解释:local i=()等同于i= 都是表示空
8.创建用户
#!/bin/bash #-------------批量增删用户 qrxx(){ if [[ ! $usernumbers =~ ^[0-9]+$ ]];then echo -e "\e[31merror parameter\e[0m" continue fi cat <<-EOF +---------------------------------------------------------+ user information userprefix: $userprefix userpass: $userpass usernumbers: $usernumbers +---------------------------------------------------------+ EOF } create(){ echo -en "\e[034mplease enter userprefix userpass usernumbers[ user 123 10 ]: \e[0m" read userprefix userpass usernumbers qrxx echo -en "\e[35mare you sure create user infomation [y|n] \e[0m" read action case $action in y|Y) for i in `seq -w $usernumbers` do user=$userprefix$i id $user &>/dev/null if [ $? -ne 0 ];then useradd $user echo "$userpass" |passwd --stdin $user &>/dev/null if [ $? -eq 0 ];then echo "$user is created..." fi else echo "$user already exists..." fi done ;; n|N) continue ;; *) echo "error action,please input [y|n]: " esac } delete(){ echo -en "\e[034mplease enter userprefix usernumbers[ user 10 ]: \e[0m" read userprefix usernumbers qrxx echo -en "\e[35mare you sure delete user information [y|n]: \e[0m" read action case $action in y|Y) for i in $(seq -w $usernumbers) do user=$userprefix$i id $user &>/dev/null if [ $? -eq 0 ];then userdel -r $user if [ $? -eq 0 ];then echo "$user is deleted..." fi else echo "$user is not exists... " fi done ;; n|N) continue esac } while : do cat <<-EOF +---------------------------------------------------------+ | MENU | | 1.Batch to create user | | 2.Batch delete user | | q.exit | +---------------------------------------------------------+ EOF echo -en "\e[33mPlease input you want to choose the mode: \e[0m" read mode case $mode in 1) create ;; 2) delete ;; q) exit ;; *) echo "error" esac done