十分钟轻松学习系列: 2020-3-20_SHELL学习_函数基础

出于对培训章节考虑,因为后续需要用函数完成各种demo,所以先粗略讲一下函数,以免在后续课程中,对函数不了解,不知道写法为何意

1. 函数创建方法:

#!/bin/bash             #固定shebang写法
IP=192.168.1.1          #定义变量: <name>=<value> 一般变量名都是大写,=左右无空格挨着写 
Add() {                 #函数头             
 	
	echo "赞美太阳~"     #函数体

}
Add                     #调用过程       

上述就是一个完整的无参数函数调用过程,可粘贴脚本内容直接在shell中运行
与其他编程语言不同,调用函数无需(),相当于直接写函数名,即完成函数调用

函数有没有位置之分??
猜测一下最上方的Add 是否可以调用下方的函数??

#!/bin/bash
Add

Add() {
    TEAM=ccb
    local TEAM=bbjyz
    echo $TEAM       
}

Add

这个坑爹的结果告诉你不能,也就是说函数定义和变量一样,开头就得全部写出来,绝对不能在函数上方调用函数!!!!!

在这里插入图片描述

有参数:注意shell语言中不存在 function xxx(args…) {} 这种写法,也就是说只能传递位参$1,$2…

#!/bin/bash
Add() {
   echo $1
   echo $2
   expr $1 + $2	 # expr函数后方 $1+$2这种方式不对,必须空格 $1(空格)+(空格)$2
}
Add 10 20  

看结果,我调用函数后传参,都属于shell脚本内部行为
在这里插入图片描述
还有一点,函数内的位参是存在作用域的,即调用函数时跟在函数后方位参数可以传递到函数内,脚本后的位参是不能传递给函数内的位参,举例说明,因为函数中有$1和$2,所以我在脚本外部传位参,结果可见,函数内部位参由于函数作用域,并不能作用到整个shell脚本

也就是说,你shell外面传参,关我函数内位参毛事儿!

在这里插入图片描述

2. 函数的作用域问题:

与一般编程语言变量作用域不同,详细学习请看:
(a) shell中任意位置,无所谓函数内、函数外,通常方法<key>=<value>定义的变量都是全局变量。
函数1中定义一个k=v,在函数2中echo $k是可以取到v的值的。
(b) 如果定义一个函数内变量又怕与函数外变量重名导致冲突,那么就需要local关键字。
函数内定义变量用 local = 的形式就可以保证该变量只能在本函数内使用。

#!/bin/bash
echo $TEAM              #因为shell是解释型语言,此时变量TEAM是不存在的,所以打印为空
Add() {
    TEAM=ccb            #全局变量TEAM,只有在本行定义后面的行才可调用它
	local TEAM=bbjyz    #局部变量TEAM,与全局同名但是完全不冲突,因为作用域不同
	echo $TEAM          #函数中有同名的全局和局部变量,函数内打印的是局部变量,也就是狭隘原则使用 ===> bbjyz
}
Add                     #调用函数
echo $TEAM              #函数外自然打印出的是全局变量,而不是局部作用域变量 ===> ccb

结果如下:如何解释?上来TEAM变量上来不存在,所以打印为空;直到函数内部的全局变量赋值,所以TEAM也就有值了,函数内local的优先级比全局变量高,所以同样定义了TEAM同名变量,但是Add函数调用结果是local变量,最后函数外部的变量当然无法使用函数内部的local变量,所以必然是全局变量
在这里插入图片描述
再看下面针对上面说明的进一步补充:

#!/bin/bash
echo $TEAM        #空       
Add() {
    TEAM=ccb            
        local TEAM=bbjyz    
        echo $TEAM     # 函数内部局部变量优先级高于全局,所以为bbjyz  
}
Add                 

Add1() {
        echo $TEAM     #函数中定义过一个全局,所以我是全局变量 ccb
}
Add1

echo $TEAM   #ccb

再看结果:
在这里插入图片描述

3. 为什么要使用函数:

优点:

  • 封装功能,提高代码复用能力,使脚本简洁易于阅读;
  • 假如计算行里每个部门成员的平均体重相较于年前胖了多少,可以写一个函数提供平均值后的差计算;
  • 只需要传入位置参数是哪个部门,部门多少人,平均体重多少,不用每个部门都写一个计算函数。

缺点:

  • 与编译语言不同,函数并不能在定义前的位置调用,这个太坑爹了!
    用Python语言举例说明,Golang对于main外定义函数,无所谓位置在哪儿,都可以调用。
     #!/usr/bin/python
     res = Add(3,1)
     print(res)
     
     def Add(x,y):
         return x+y
     
     res = Add(3,1)
     print(res)
    
    结果同样坑爹,解释性语言就这德行,告诉你没定义呢你丫调用啥?。。。
    在这里插入图片描述
    在定义Add之后,再调用,就不会有任何问题:0
    在这里插入图片描述
    在这里插入图片描述

这里又引出一个知识点,上面shell中生生让我写出一个python函数??我是通过什么区分shell脚本还是python脚本的??我从第一天开始说的Shebang,Shebang,Shebang,什么是Shebang???

网上一堆长篇大论,有兴趣看一看,我给缩减成如下几句话:

  • shebang不是注释!不是注释!不是注释!!
  • shebang可以让不同解释器在脚本中完成不同的工作,一些复杂逻辑可择优选择易实现语言
  • 不同shebang可以实现同一个shell脚本中,不同语言嵌套关系,这个我明天讲,有些测试还需要做
发布了49 篇原创文章 · 获赞 18 · 访问量 3990

猜你喜欢

转载自blog.csdn.net/weixin_41047549/article/details/104988762