举例说明Linux shell中local、export的常用用法和要注意的问题
一、前言
在【Linux shell】中,【local】和【export】通常被拿来控制shell中变量的作用域。export被用到的场合会更多一些,local只能被用在shell函数中。
二、直接上例子
为了方便理解,尝试写三个简单的shell脚本。
命令【yjcmd】:首先用shell模拟一个有输出的,返回值为错误值的命令。
shell【yjshell.sh】:写一个【local】、【export】和【默认shell变量】放在一起对比的【例子shell】。
子shell【yjchildshell.sh】:为了表达变量在shell间传递,写一个【子shell】,【子shell】中尝试访问【yjshell.sh】中的【三种】类型的变量。
1、【yjcmd】
这个命令的作用是输出【yjtest】,并且返回【1】,代表命令执行错误。
2、【yjshell.sh】
3、【yjchildshell.sh】
三、执行结果
注:【bash】和【dash】中,结果都如上图所示,没有差别。
四、基本规律总结
基本规律大多数常写shell脚本的人都非常清楚,这里不过多讨论,简单总结下。
从【三、】的执行结果中可以清晰看出:
1、默认变量可以在【yjshell.sh】的任意位置访问到,但是【不能】被【子shell】【yjchildshell.sh】继承。
2、被【local修饰】的变量只在【当前shell函数】中生效,【yjshell.sh】的其它地方并不能得到这个变量的值,并且【子shell】也无法继承它。
3、被【export修饰】的变量其实已经成为了【当前shell】的【环境变量】,可以被【当前shell】以及【当前shell调用的子shell】访问到。
注:虽然export修饰的变量【作用范围变大】,但是其仅限于【当前shell环境】和【被其调用的子shell】中,并不能影响到其【父shell】(这里例子没有展示,简单来说就是当前shell环境中export的内容,当前shell的父shell无法访问)。
五、例子中的坑
我们可以看到例子中,关于函数内的打印,多了一个【$?】的输出,【$?】是用来获取上一条命令执行结果值的。
可以看到【yjcmd】这个命令中,命令的输出内容是【yjtest】,命令的返回值是【1】,想要表达这个命令执行出错了,返回了错误值。
通常情况下,shell脚本中的变量赋值并不会影响【$?】的数值,因为变量赋值不属于命令范畴。
但是当命令执行的输出被赋值给三种类型变量后,【$?】的输出却并不相同。
六、关于坑的探索
出现这个问题的初期,确实挺令人不解的,明明只是几个不同作用域的变量,被【yjcmd】命令的输出赋了值,为何会导致后续的【$?】命令取值发生了变化。
带着这个问题探索了很长时间的百度,并没有什么收获。
后来回归【local】和【export】的定义时,被“点醒”了。
【local】和【export】的定义中,对【local】和【export】的名词定性为【命令】。
我们都知道,当描述一个物体时,通常会用形容词+名词的方式进行表达,形容词通常用来说明这个【物体的性质】,名词用来表达这个【物体的本质】。
例如面试中最为经典的【指针数组】和【数组指针】的概念区分,英文描述中借助的就是这个原理,用名词部分区分这两个概念的本质。
既然【local】和【export】的本质被定义为【命令】,那么这就代表【local】和【export】就具备了命令的通用特性,具备【返回值】。
所以说例子中,命令执行,命令输出被赋值给了变量,变量被【local】和【export】修饰相当于执行了一条命令。
换句话说,被修饰的变量作用域缩小或是扩大是【local】和【export】命令作用的结果,因此【$?】的值就是【local】和【export】命令执行的返回值。
因此也就可以解释为什么【yjcmd】明明返回的是【1】,但是【$?】的输出确实【0】了。
七、关于坑的总结
这个小小的问题如果不被关注,可能会导致一个巨大的bug,这里记录下来用来给自己提个醒。
需要获取命令执行成功与否时,如果想通过返回值的方式进行判断,那么就不要将命令的输出【直接赋值】给【local】【export】修饰的变量。
如果必须要【直接赋值】给【local】或【export】修饰的变量,那就尝试通过【命令输出】判断命令执行的结果,而不是通过【$?】来判断。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架