Shell变量作用范围

目录

1、函数内的变量

2、shell脚本内的变量

3、进程内的变量

4、进程间的变量

5、终端间的变量

6、用户间的变量

总结


本文内容同微信公众号【凡登】,关注不迷路,学习上高速,欢迎关注共同学习。

什么是变量的作用范围? 变量在Shell脚本中的有效范围或可使用的范围, 什么是有效范围或可使用范围? 通过看一个示例看看

# 定义一个变量
[root@ ~]# name=joey
# 编辑脚本hi.sh 内容为:echo "$name, hello",定义以脚本方式查看变量
[root@ ~]# vim hi.sh
echo "$name, hello"
# 当前终端查看
[root@ ~]# echo "$name, hello"
joey, hello
# 当前bash进程查看,能查看到变量
[root@ ~]# source ./hi.sh
joey, hello
# bash子进程查看,不能查看到变量
[root@ ~]# bash hi.sh
, hello
# 新启终端查看,不能查看到变量
[root@ ~]# echo "$name, hello"
, hello
# 回到最初终端,导出变量后可以查看到,
[root@ ~]# export name ; bash hi.sh
joey, hello

从上面可以看到,当前进程和终端可以访问当前定义的变量,而子进程和新启终端访问不到变量,

当回到原终端通过export导出变量后,这时子进程可以访问到变量,然而新终仍然无法访问到变量,这是什么原因? 它就是本小节将要介绍的主题:变量的作用范围

这里从简单到复杂,依次递进的方式将变量作用范围分为以下6种场景:函数内的变量shell脚本内的变量进程内的变量进程间的变量终端间的变量用户间的变量

1、函数内的变量

函数内的变量也就是局部变量。看下示例

[root@ ~]# vi fun.sh 
#!/bin/bashfunction my_fun() {  echo "--------函数开始--------------"local local_var1="我是函数局部变量"  # 定义局部变量 var  echo "执行函数:$local_var1 !"  # 输出局部变量的值  echo "--------函数结束--------------"
}echo "执行函数前:$local_var1 !"
my_fun  # 执行函数
echo "执行函数后:$local_var1 !"[root@ ~]# bash fun.sh 
执行函数前: !
--------函数开始--------------
执行函数:我是函数局部变量 !
--------函数结束--------------
执行函数后: !

小结:局部变量在函数中有效,超过函数范围就失效

那可以在shell脚本中定义局部变量? 不可以。局部变量只能在函数中定义,

如下图错误示例:

[root@ ~]# vim fun_local_err.sh 
local v=123
[root@ ~]# bash fun_local_err.sh 
fun_local_err.sh: line 1: local: can only be used in a function[root@ ~]# local vv=123
bash: local: can only be used in a function

2、shell脚本内的变量

在shell脚本中定义的变量作用范围分为:局部变量和全局变量,局部变量在某个区域内有效,如函数块内。全局变量时整个shell脚本运行中有效,一旦脚本运行结束,全局变量就会失效。这里重点介绍全局变量

[root@ ~]# vi fun.sh 
#!/bin/bash
global_var1="我是脚本全局变量"function my_fun() {  echo "--------函数开始--------------"global_var2="我是函数全局变量"echo "执行函数:$global_var2 !"echo "--------函数结束--------------"
}echo "执行函数前:$global_var1 !"
echo "执行函数前:$global_var2 !"
my_fun  # 执行函数
echo "执行函数后:$global_var1 !"
echo "执行函数后:$global_var2 !"[root@ ~]# bash fun.sh 
执行函数前:我是脚本全局变量 !
执行函数前: !
--------函数开始--------------
执行函数:我是函数全局变量 !
--------函数结束--------------
执行函数后:我是脚本全局变量 !
执行函数后:我是函数全局变量 !

全局变量作用域在shell脚本都有效,访问前必须先定义好变量。忽略是否在函数中定义,如例子所示,即使在函数中定义,当函数执行完后,全局变量仍有效。

总结:局部变量只能在函数中定义和使用,且作用域在函数内。全局变量作用范围在整个脚本中,需要注意定义变量位置需在访问之前,且不受函数作用域范围的影响

3、进程内的变量

进程内变量描述的是bash进程中的变量。

在介绍进程内变量之前,先回顾下脚本执行不同方式所带来的影响,

bash xxx.sh 新起子进程执行xxx.sh , 脚本中行为只在子进程有效,对父进程环境没影响,

source ./xxx.sh 在当前进程执行xxx.sh ,脚本行为对当前进程环境有影响。

. xxx.sh 是source ./xxx.sh简写形式

./xxx.sh 新起子进程执行xxx.sh,

4种不同执行方式和区别详情参见《shell简单认知》脚本的执行方式。回到本节主题进程变量的作用范围

# 新建脚本hi.sh,内容为echo "$name, hello"
[root@ ~]# echo 'echo "$name, hello"' > hi.sh
# 当前进程新建变量name=123
[root@ ~]# name=123
[root@ ~]# echo $name
123# bash xxx.sh执行脚本,以子进程方式访问访问父进程name
[root@ ~]# bash hi.sh
, hello# source ./xxx.sh执行脚本,在当前进程访问name
[root@ ~]# source hi.sh
123, hello
# . xxx.sh 是 source ./xxx.sh的简写形式
[root@ ~]# . hi.sh
123, hello# ./xx.sh子进程方式执行脚本
[root@ ~]# chmod u+x hi.sh
[root@ ~]# ./hi.sh
, hello

以上执行结果表明,同一进程变量访问不受限制,但子进程无法访问到父进程变量, 进程中的变量作用仅在当前进程的范围内有效,即进程变量也有自己的作用范围。

问:如何跨进程访问,让子进程也可以访问父进程变量,实现进程间的变量共享?

第4节《进程间的变量》

4、进程间的变量

进程间变量描述的是父子进程间变量。被export关键字修饰的变量,可以在进程间传递,也可以被子进程继承,从而在进程间实现变量共享。在第3节《进程内变量》例子中 bash hi.sh 访问不到name, 那么用export修饰name,再看执行结果

# 导出当前变量
[root@ ~]# export name# bash xxx.sh 方式访问父进程变量name
[root@ ~]# bash hi.sh
123, hello
# ./xxx.sh 方式访问父进程变量name
[root@ ~]# ./hi.sh 
123, hello

执行结果看出,当用export修饰name变量后,就可以访问父进程name变量。

export命令设置的变量是环境变量

环境变量是在操作系统中用于存储各种配置信息的一种机制,通过设置环境变量,可以影响系统的行为和程序的运行。使用export命令,可以将一个变量从当前shell传递到子shell或其他进程中。当一个变量被导出后,它将成为子shell的环境变量,可以被其他命令和程序访问和使用

5、终端间的变量

在上一节学习了通过export修饰的变量可以在进程间传递,从而实现进程共享变量,那么能否在多个终端共享变量?先通过一个示例看看,在上述第4节《进程间的变量》例子中,新启一个终端,访问变量

# 新启终端访问
[root@ ~]#bash hi.sh
, hello

发现新启终端无法访问到上述通过export导出的环境变量,那么如何实现终端间的变量共享?

[root@ ~]# vim ~/.bashrc
export name=456# 使用source ~/.bashrc加载配置文件
[root@ ~]# source ~/.bashrc 
# 访问可以看到原值123已经变为456
[root@ ~]# bash hi.sh
456, hello# 新启终端访问,可以访问到最新值456
[root@ ~]#bash hi.sh
456, hello

说明:

1、修改~/.bashrc,如果不使用source ~/.bashrc加载,那么访问的仍然是原来的值;

当前终端立即访问,则需要通过source ~/.bashrc重新加载配置

新终端会重新加载配置,无需再使用source ~/.bashrc加载配置文件

2、写入~/.bashrc中的变量可以跨终端进行访问

在bashrc中修改的值无法被立即访问,是因为修改的变量只在当前Shell进程中生效,而不会影响到父进程或其他子进程。当在bashrc中添加或修改环境变量时,这些变量只会对当前Shell及其子进程起作用,而不会影响其他已经运行的Shell或系统级的环境变量

如果你希望在脚本中访问在bashrc中定义的变量,可以在脚本中通过source命令加载~/.bashrc文件。这样,脚本就会继承bashrc中定义的所有变量和配置。

通过上述bashrc配置文件实现终端共享变量。

6、用户间的变量

在上一节学习了通过export修饰的变量可以在进程间传递,从而实现进程共享变量;通过~/.bashrc配置变量实现跨终端共享变量,那么能否在不同用户间共享变量?先通过一个示例看看

# 创建新用户
[root@ ~]# useradd joy
[root@ ~]# passwd joy# 创建脚本访问name和NAME变量
[root@ ~]# vi hi.sh 
echo "$name, hello"
echo "$NAME, hello"
echo "$_name, hello"
# 将root脚本复制到用户joy家目录下
[root@ ~]# cp /root/hi.sh /home/joy/# 定义name和NAME,_name变量
[root@ ~]# name=123
[root@ ~]# export NAME=456
[root@ ~]# vim ~/.bashrc
export _name=123456# 加载bashrc配置文件
[root@ ~]# source ~/.bashrc 
# root用户下访问变量
[root@ ~]# source ./hi.sh 
123, hello
456, hello
123456, hello# 切换joy用户, 使用-表示用户登录加载所有配置文件
[root@ ~]# su - joy 
# joy用户下执行脚本访问变量
[joy@ ~]$ source ./hi.sh 
, hello
, hello
, hello

上面演示,不管是shell全局变量或通过export修饰的环境变量,还是定义在~/.bashrc配置文件的变量,当切换到新用户后都访问不到。说明这些不具备跨用户共享,那么如何才能做到切换用户仍然可以访问变量?

让我们在/etc/bashrc配置文件中新增变量,再观察一下

# 新增变量
[root@ ~]# vim /etc/bashrc
export _NAME=123456789
# 加载配置文件
[root@ ~]# source /etc/bashrc# 在hi.sh后追加对_NAME的访问
[root@ ~]# vim hi.sh
echo "$_NAME, hello"
# 移动到joy用户家目录下
[root@ ~]# cp /root/hi.sh /home/joy/# root用户下访问
[root@ ~]# source ./hi.sh 
123, hello
456, hello
123456, hello
123456789, hello# 切换joy用户并登录
[root@ ~]# su - joy
# joy用户下访问变量,哎,这回可以访问_NAME变量,
[joy@ ~]$ source ./hi.sh
, hello
, hello
, hello
123456789, hello

注:编辑/etc/bashrc需要root权限

从上面结果可以看出当切换用户后,定义在/etc/bashrc下的变量仍可以访问,至此我们自定义的变量,实现了跨进程,跨终端,跨用户进行访问了。

总结

通过示例演示从函数->脚本->进程内->跨进程->跨终端->跨用户不同场景中变量表现,引出变量的作用范围,使用local修饰变量使变量的作用范围控制在函数内,在脚本中定义变量可以在函数中共享,通过使用export修饰变量使其能在进程间传递,实现进程间共享变量,扩大变量作用范围,另外修改配置文件~/.bashrc/etc/bashrc能使变量在多个终端和用户间共享,进一步扩大变量的作用范围,在日常工作中我们根据不同场景来限定变量范围,防止误伤。

问:~/.bashrc /etc/bashrc配置文件是什么?为什么可以实现变量共享?还有没有类似配置文件?

这些就是变量的配置文件,将在《变量配置文件》中讲解。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/158043.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在Linux服务器中查找mysql的配置文件并修改其内容并保存,清空mysql8.0以上默认开启SSL的配置,防止odbc无法连接的问题

------每个命令输完记得按【enter】回车键------- 1、查找mysql的配置文件命令-mysql的配置文件默认名是my.cnf: find / -name my.cnf 2、查看显示的配置文件内容: cat /etc/my.cnf 3、修改配置文件的内容: 使用vi 或vim 命令 vi /etc…

推荐系统概述(PPT)

参考资料: 推荐系统系列之推荐系统概览(上) | 亚马逊AWS官方博客推荐系统系列之推荐系统概览(下) | 亚马逊AWS官方博客 目录如下: 推荐系统简介 推荐系统中常见概念 推荐系统中常用的评价指标 首页推荐…

请求的接口响应状态为已取消的原因

有趣的iframe问题 今天遇到一个问题,当点击了按钮----跳转页面时----F12键点击网络中的状态报了已取消,类型是 document说明是前端页面的问题,如果是xhr那可能是接口的问题。 原本是写了3个iframe,页面刷新的时候请求了第一个iframe,然后就…

随机微分方程的MATLAB数值求解

dt0.01; tout200; %总时间为2 xzeros(1,tout); x(1)0.5; %初始位置 mu0.2; sigma1; Wtsqrt(dt)*randn(1,tout); %产生随机序列Wt for t1:tout-1x(t1)x(t)mu*x(t)*dtsigma*x(t)*Wt(t); end t11:10:tout; %对原时间序列进行抽样 xtzeros(1,length(t1)); i1; for tt1xt(i)0.5*exp(…

招投标系统软件源码,招投标全流程在线化管理

功能描述 1、门户管理:所有用户可在门户页面查看所有的公告信息及相关的通知信息。主要板块包含:招标公告、非招标公告、系统通知、政策法规。 2、立项管理:企业用户可对需要采购的项目进行立项申请,并提交审批,查看所…

【git-分布式版本控制工具】

Git git介绍 分布式版本控制系统工具 vs 集中式版本控制工具git安装 基于官网发布的最新版本2.31.1 安装讲解git命令 基于开发案例 详细讲解了git的常用命令git分支 分支特性 分支创建 分支转换 分支合并 代码合并冲突解决IDea 集成 git Github 创建远程库代码推送 PUSH代码…

HUAWEI华为MateBook X Pro 2022 12代酷睿版(MRGF-16)笔记本电脑原装出厂Windows11系统工厂模式含F10还原

链接:https://pan.baidu.com/s/1ZI5mR6SOgFzMljbMym7u3A?pwdl2cu 提取码:l2cu 华为原厂Windows11系统工厂包,带F10一键智能还原恢复功能。 自带指纹、面部识别、声卡、网卡、显卡、蓝牙等所有驱动、出厂主题壁纸、Office办公软件、华为…

深信服AC跨三层取mac,绑定ip/mac

拓扑图 目录 拓扑图 1.交换机配置团体名和版本号 2.配置跨三层取mac 3.配置策略 验证: “您的每一次阅读、点赞和分享,都是对我最大的鼓舞和动力。” 如果对亲爱您有所帮助,可以尝试支持一下博主,让博主更有动力 1.交换机配置…

Docker上部署mysql(超简单!!!)

拉取mysql镜像 运行如下命令 docker pull mysql:5.7 拉取成功 查看镜像 运行容器 此处部署最新版本的mysql docker run -d --name mysql -p 3307:3306 -e TZAsia/Shanghai -e MYSQL_ROOT_PASSWORD111 mysql --name mysql:给容器起个名字(唯一&#xff…

可靠性工程师的发展之路

都是经验之谈,不懂产品,只靠理论 ,注定行不通。可靠性工程师的成长,是一个专业与产品共同前进的道路。 1、轻易不要想着建可靠性体系。 如果可靠性还处在一穷二白的程度,建可靠性体系只会害了公司,不仅浪…

js中数组去重(数组中元素是对象)

一、使用 Set 对象: const arr [{ id: 1, name: A },{ id: 2, name: B },{ id: 1, name: A },{ id: 3, name: C } ];const result Array.from(new Set(arr.map(item > JSON.stringify(item)))).map(item > JSON.parse(item)); console.log(result); 二、…

bclinux aarch64 openeuler 20.03 LTS SP1 部署 fastCFS

基于已配置好的4个节点部署ceph-0 ceph-1 ceph-2 ceph-3(早期ceph测试环境,名称就不修改了) 获取fcfs.sh mkdir /etc/fcfs cd /etc/fcfs wget http://fastcfs.net/fastcfs/ops/fcfs.sh 配置/etc/fcfs/fcfs.settings # 要安装的集群版本号…

Linux 零拷贝splice函数

Linux splice 函数简介 splice 是 Linux 系统中用于在两个文件描述符之间移动数据的系统调用。它的主要作用是在两个文件描述符之间传输数据&#xff0c;而无需在用户空间进行数据拷贝。也是零拷贝操作. 函数原型 #include <fcntl.h> ssize_t splice(int fd_in, loff_…

Python 2.7 在 Debian 服务器上获取 URL 时的 SSL 验证失败问题与解决方案

在使用Python的requests库从Debian稳定服务器上获取简单URL时&#xff0c;遇到了SSL证书错误。 根据用户的问题描述&#xff0c;您遇到了SSL证书验证失败的问题。 要解决这个问题&#xff0c;您可以采取以下步骤&#xff1a; 1. 升级到Python 2.7的最新版本&#xff1a; 首…

重排和重绘

浏览器的渲染过程 1.解析HTML&#xff0c;生成DOM树 2.解析CSS&#xff0c;生成CSS规则树(CSSOM) 3.合并DOM和CSSOM&#xff0c;生成渲染树&#xff08;Render-Tree&#xff09; 4.计算渲染树的布局&#xff08;Layout&#xff09; 5.将布局渲染到屏幕上(paint) 什么是重…

关于sklearn的:还可能是网络的问题???

前提&#xff1a;安装sklearn需要 numpy、scipy等库&#xff08;这个自行搜索&#xff09; 昨天安装numpy、scipy很快&#xff0c;一会就好了&#xff0c;然后安装sklearn一直报错&#xff0c;还以为是版本问题。 今天大早上起来&#xff0c;再次安装&#xff0c;顺利成功&…

Doris安装要求

软硬件需求 1&#xff09;Linux 操作系统要求 2&#xff09;软件需求 3&#xff09;开发测试环境 4&#xff09;生产环境 5&#xff09;注意事项 &#xff08;1&#xff09;FE 的磁盘空间主要用于存储元数据&#xff0c;包括日志和 image。通常从几百 MB 到几个GB 不等。 &a…

minio安装使用-linux

下载地址&#xff1a;MinIO | Code and downloads to create high performance object storage 选择 minio server 可以直接下载二进制文件。 将下载的文件传输到服务器的指定文件夹下&#xff0c;如 /opt/minio。 然后在&#xff0c;命令行启动minio&#xff1a; /opt/mini…

C#入门(8):抽象类介绍

在C#中&#xff0c;抽象类&#xff08;Abstract Class&#xff09;是一种特殊的类&#xff0c;它不能被实例化。相反&#xff0c;它通常作为基类&#xff0c;供其他类继承。抽象类可以包含抽象成员&#xff08;抽象方法、抽象属性、抽象事件或抽象索引器&#xff09;&#xff0…

QT在线安装指南

方案 https://mirrors.tuna.tsinghua.edu.cn/qt/official_releases/online_installers/Index of /qt/official_releases/online_installers/ | 清华大学开源软件镜像站&#xff0c;致力于为国内和校内用户提供高质量的开源软件镜像、Linux 镜像源服务&#xff0c;帮助用户更方…