shell函数

87 阅读3分钟

shell函数

shell

  • Shell 函数的本质是一段可以重复使用的脚本代码,这段代码被提前编写好了,放在了指定的位置,使用时直接调取即可。 Shell 中的函数和 C++ 、 Java 、 Python 、 C# 等其它编程语言中的函数类似,只是在语法细节有所差别。
  • 使用函数可以将大的工程分割为若干个小的功能模块,代码的可读性更强

shell函数定义

【1】
function    函数名 {
       命令序列
}


【2】
函数名(){
    命令序列
}
bash
复制代码
#!/bin/bash

function  test1  {
#外部循环定义行
for ((a=1; a<=9; a++))
do
  #内部循环定义列
  for ((b=1; b<=a; b++))
  do
       c=$[a * b]
       echo -n -e "$a*$b=$c\t"
  done
  #每行所有列输出完毕后进行换行
  echo ' '
done
}


############## main ###############
test1
#!/bin/bash

test2 () {
#外部循环定义行
for ((a=1; a<=9; a++))
do
  #内部循环定义列
  for ((b=1; b<=a; b++))
  do
       c=$[a * b]
       echo -n -e "$a*$b=$c\t"
  done
  #每行所有列输出完毕后进行换行
  echo ' '
done
}



############## main ###############
test2

函数返回值:

return 表示退出函数并返回一个退出值,脚本中可以用$?变量显示该值

使用原则:

  • 函数一结束就取返回值,因为$?变量只返回执行的最后一条命令的退出状态码
  • 退出状态码必须是0~255,超出时值将为除以256取余

#!/bin/bash

function test1 {
    read -p "请输入一个整数: " num
   echo $[num * 2]

}


result=$(test1)

echo $result

[root@localhost ~]# sh demo30.sh
请输入一个整数: 300
88

$()意思是:他可以用于获取括号里面命令的返回值

#!/bin/bash

function test1 {
    read -p "请输入一个整数: " num
   echo $[num * 2]

}


result=$(test1)

echo $result

[root@localhost ~]# sh demo30.sh
请输入一个整数: 400
800

shell函数的传参

#!/bin/bash

test() {
  sum=$[$1 + $2]  //$是位置变量
  echo $sum

}

test 10 20    


[root@localhost ~]# sh demo31.sh
30

括号里面的 $1 $2 属于位置变量会按照设定好的值给出运算的结果
#!/bin/bash

test() {
  sum=$[$1 -  $2]
  echo $sum

}

test $1 $2

[root@localhost ~]# sh demo31.sh  50   30
20
#!/bin/bash

test() {
#在函数体内的$1  $2 ..代表的是调用函数时函数后面根的位置参数
  sum=$[$1 -  $2]
  echo $sum

}
#函数体外的$1 $2..代表的是执行脚本时脚本后面根的位置参数
test $2 $1
[root@localhost ~]# sh demo31.sh  50   30
-20
在函数体外面的代码test $2 $1 后面跟的位置变量,
此时test $2 $1   $2对应的应该是50  $1对应的应该是30
因为在我们输出命令的时候sh demo31.sh 相当于$0  50相当于$1  30相当于$2
#/bin/bash
#定义一个用于十进制转二进制的函数
bin() {
   SUM=''
   NUM=$1
   for i in {1..8}
   do
       SUM=$[NUM % 2]$SUM
       let NUM/=2
    done
    echo $SUM
}

#定义与分割IP的函数
SPT() {
  IP=$1
  for i in {1..4}
  do
     num=${IP%%.*}
     IP=${IP#*.}
     #使用 bin 函数转换
     BIN=$(bin $num)
     echo -n $BIN.
   done
}


read -p "请输入你要转换的IP地址: " SIP
RES=$(SPT $SIP)
#删除末尾的 .
echo ${RES%.*}
~


[root@localhost ~]# . demo22.sh
请输入你要转换的IP地址: 192.168.30.120
11000000.10101000.01010101.01111000

函数变量的作用范围

  • 函数在Shell脚本中仅在当前Shell环境中有效。(即定义和调用函数要在同一个shell环境中)

  • 脚本中定义的变量,仅在当前shell环境中有效。

    • 如果使用source . 执行脚本,那么该变量在命令行也会生效,因为这两种方式没有打开子shell环境,而是在当前shell环境中执行脚本。一般建议不要使用source和. 来执行脚本,可能会影响系统资源配置。
  • Shell脚本中变量默认全局有效。(即在整个脚本中都生效,并非是环境变量)

  • 将变量限定在函数内部使用 local 命令。这样变量只在当前函数内有效,不影响脚本中的其他函数和变量。

bash
复制代码
#!/bin/bash
i=8
i=9
echo$i

QQ截图20220902165632.png

local设定局部变量

#!/bin/bash

myfun() {
#想把变量设定在函数内部使用,就要使用把 local 写在函数体前面,这样就可以>将函数变为局部变量
local i
i=8
echo $i

}
i=9
myfun
echo $1


[root@localhost ~]# . 1.sh
8

QQ截图20220902170531.png

递归

递归就是一个函数在它的函数体内调用它自身。执行递归函数将反复调用其自身,每调用一次就进入新的一层。所以递归要有两个基本要素,结束条件与递推关系。

阶乘

例如所要求的数是4,则阶乘式是1×2×3×4,得到的积是24,24就是4的阶乘。 例如所要求的数是6,则阶乘式是1×2×3×……×6,得到的积是720,720就是6的阶乘。例如所要求的数是n,则阶乘式是1×2×3×……×n,设得到的积是x,x就是n的阶乘。

#!/bin/bash

a=1
for ((i=10; i>=1; i--))
do

   a=$[i * a]


done
echo $a

[root@localhost ~]# . 1.sh
3628800
#!/bin/bash

fact() {
   #如果你舍定的阶乘为1
   if [ $1 -eq 1 ]
   then
      echo 1
   #如果不等于1
   else
   #local设定了temp为局部变量  等于函数传参的值-1
   local temp=$[$1 - 1]
   #result结果等于函数名加上-1的值
   local result=$(fact $temp)
   echo $[$1 * $result]
   fi
}

read -p "请输入一个正整数:" n
result=$(fact $n)
echo "$n阶乘的值为 $result "

[root@localhost ~]# . 1.sh
请输入一个正整数:23
23阶乘的值为 8128291617894825984

QQ截图20220902172949.png

递归目录

#!/bin/bash

list_dir() {
   for dir in $1/*
   do
     if [ -d $dir ];then
     echo "$dir 为目录:"
     list_dir "$1/$dir"
   else
     echo "$dir 为文件"
     fi

   done
}

list_dir "/root/bin"


[root@localhost bin]# . 9.sh
/root/bin/9.sh 为文件
/root/bin/aa 为目录:
/root/bin//root/bin/aa/* 为文件

函数库

  • 我们可以事先创建一个函数库文件,在里面定义各种常用的函数,然后可以在别的shell脚本中直接引用这个函数库文件,使得不需要再次定义函数即可直接调用函数。
  • 我们可以事先创建一个函数库文件,在里面定义各种常用的函数,然后可以在别的shell脚本中直接引用这个函数库文件,使得不需要再次定义函数即可直接调用函数。

建立一个函数库

[root@localhost bin]# vim h1.sh
#!/bin/bash
#加减乘除函数库
 
jiafa () {
     echo $[$1+$2]
}

jianfa () {
     echo $[$1-$2]
}

chengfa () {
     echo $[$1*$2]
}
 
chufa () {
     if [ $2 -eq 0 ]
     then
         echo "除数不能为0"
     else
         echo $[$1/$2]
     fi
}    
#!/bin/bash
#调用函数库文件,注意要使用source或.来调用
. /root/bin/h1.sh

read -p "请输入第一个正整数:" a
read -p "请输入第二个正整数:" b

#调用函数
r1=$(jiafa $a $b)
r2=$(jianfa $a $b)
r3=$(chengfa $a $b)
r4=$(chufa $a $b)

#输出结果
echo "$a$b的结果是:$r1"
echo "$a$b的结果是:$r2"
echo "$a$b的结果是:$r3"
echo "$a除以$b的结果是:$r4"



请输入第一个正整数:6 
请输入第二个正整数:3 
6加3的结果是:9 
6减3的结果是:3 
6乘3的结果是:18 
6除以3的结果是:2