shell脚本中的变量

关于Linux操作系统中当前shell进程与子shell进程的详细解释

如上图所示,使用ps -f可以当前查看Linux操作系统中当前正在运行的进程。

然后敲bash后,相当于在当前的bash shell环境下又创建了一个子bash shell的进程,

如上图所示,后来创建的bash shell的PPID是前一个bash shell的PID

使用./hello.sh的方式去调用脚本就相当于是在原来bash shell的基础上又开了一个子bash shell,然后在子bash shell中去调用脚本。 

敲exit命令时会发现没有退出Linux操作系统就在于当前是在子shell进程中,

开子shell与不开子shell的区别就在于,环境变量的继承关系,如在子shell中设置的当前变量,父shell中是不可见的。

系统预定义变量

在shell编程中存在系统变量和用户变量,其中系统变量的作用范围是全局,而用户变量的作用范围却是分为全局变量和局部变量。

局部变量是只对当前的bash起效。

Linux操作系统中shell编程的系统变量大部分是全局变量,小部分是局部变量。

$HOME表示当前用户的家目录,$PWD表示当前用户的工作目录,$SHELL表示当前的shell会话,$USER表示当前的用户,

如果想查看当前所有的全局环境变量的话,就是用env,printenv的功能和普通的env大致是一样的。

如果想使用系统变量,就使用echo或者printenv加系统变量。

如上图所示,如果只是想查看当前系统变量的值的话,加不加$符无所谓但是如果想使用系统变量的值的话,就必须加上$了。

在Linux操作系统中可以使用set命令可以用来显示当前所有的shell变量(包括环境变量)及其值。

用户的自定义变量

如上图所示,在Linux操作系统中shell编程语言中关于用户变量的定义只需要变量名=变量值,就可以直接定义变量,不需要像其他编程语言一样去定义变量的类型再去给变量赋值,如果变量值中有空格就需要我们将将变量值用引号引起来才能生效,这时定义的变量属于用户变量中的局部变量,即在原来的bash环境中有,在子bash中没有,

可以使用set | grep my_var这样的命令来查找用户创建的变量的值,

如上图所示,在新创建的子bash中,echo $my_var发现不输出变量的值,这就说明用户创建的my_var是一个局部变量。

如上图所示,在子bash中找不到用户创建的变量的值,但是退出子bash后,可以查找到用户创建的变量的值,说明这时一个用户变量中的局部变量,如果像把局部变量定义成全局变量的话,如下图操作。

如上图所示,如果我们想定义一个全局变量它的作用范围是在-bash以及嵌套的bash中有效,

这就需要使用export 变量名称,来将用户创建的局部变量定义为一个全局变量,这时再创建一个bash环境,进入到这个子bash环境时,echo 变量名称,发现变量的值就可以输出打印了。

如果在子bash中对这个变量进行变量值的修改时,再进入到别的bash环境中,就发现原来变量的值并没有改变,

所以对这个全局变量的修改只在修改界面中的bash中有效,在其他的bash环境中对变量的修改操作无效。当然如果在子bash中对变量进行更改后,使用export 变量名称,这时子bash包括它嵌套的子bash中修改的变量值都是可以看到的。

如上图所示,在子bash中对全局变量进行数值修改以后,再将变量重新定义为全局变量时,切换到-bash环境中依然看不到对变量的修改操作,所以在子bash中对变量进行更改后,使用export 变量名称,这时子bash包括它嵌套的子bash中修改的变量值都是可以看到的。但是在子bash以外的bash环境中看不到对变量的修改操作。

在不同bash环境中对脚本的调用

如上图所示,在脚本hello.sh中加上了一个变量,当调用这个脚本的时候,就可以打印输出这个变量的值,而随着调用脚本的bash环境不同,其调用脚本的结果也不同,当使用source 调用脚本的时候,bash环境是当前的bash环境,而使用./hello.sh来调用脚本的时候,bash环境就是当前bash环境的子bash环境,

这时定义一个用户变量中的局部变量,然后在脚本hello.sh中添加这个变量,发现在当前bash环境中的子bash环境中这个局部变量是不生效的。而如果以. hello.sh或者source hello.sh来在当前bash环境中调用这个脚本局部变量就可以生效。

如果使用export 局部变量名称,这时该局部变量就变成了全局变量,这时再使用./hello.sh(在当前bash环境下启动一个子bash,或者给脚本添加x执行权限,直接通过调用脚本路径的方式来调用脚本)这样的方式来调用脚本,该脚本中的两个变量都生效。

全局变量,只读变量和撤销变量

如上图所示,使用echo 加变量名称,就可以打印变量值,对于shell编程来说,变量名=变量值,这期间没有能对变量值进行运算的操作,如果想对变量值进行运算就需要使用a=$[5+9]或者是a=$((1+5))这样的操作。

这里是关于shell编程的运算符的介绍,

只读变量

这里的意思就是说定义一个常量,此时这个变量中的变量值只能进行读的操作,不能对这个变量值进行修改。

如上图所示,这是在定义一个只读变量,使用readonly 变量名称=变量值,这就是在shell中定义了一个只读变量,如果此时想修改这个变量的变量值,就会被提醒,这是一个只读变量,不能进行对变量值的修改操作。

撤销变量

如上图所示,如果你想撤销一个变量的话,直接unset 变量名,就可以将该变量撤销掉,撤销变量的意义在于该变量没有用处时,撤销掉,节省内存空间。

在shell编程中如果将一个变量定义为一个只读变量,此时直接用unset 变量名称,是不可以撤销这个只读变量的,需要先将这个只读变量的只读状态撤销掉。

如果你确实需要“撤销”这个只读状态,可以采取以下策略之一:

  1. 重新声明变量:你可以在新的Shell作用域中重新声明这个变量,这样就绕过了原来的只读限制。这通常意味着在子shell中或者一个新的脚本进程中来做这件事,因为父shell中的只读属性不会传递给子进程。

     Bash 
    1# 在子shell中重置变量
    2(
    3  myVar="New Value"
    4  echo "$myVar"  # 输出 "New Value"
    5)
    6echo "$myVar"  # 回到父shell,输出仍是 "Hello World"
  2. 使用unset后再重新赋值:注意,unset命令可以删除一个变量,包括只读变量,但这仅在该变量不是全局只读变量时有效。之后,你可以重新声明该变量。但请注意,这实际上是“删除并重新创建”,而非直接撤销只读属性。

     Bash 
    1# 如果变量不是全局只读,可以先unset再赋值
    2unset myVar
    3myVar="New Value"
  3. 避免使用readonly:在设计脚本时,如果预见需要改变变量的值,最初就不要将其声明为只读。

由于Shell中没有直接撤销只读属性的命令,理解和规划你的脚本结构以适应这种限制是很重要的。在大多数情况下,只读变量是用来防止意外修改关键数据的,因此撤销只读状态应当谨慎考虑其必要性。

如何将脚本当作命令一样去使用呢?(前提在不改变/bin/目录内容的前提下.)

如上图所示,可以将脚本的名称cp 复制到/bin/下,此时对于脚本的调用就可以像正常的命令一样,但是/bin/是Linux操作系统储存命令shell脚本的地方,特别不建议对/bin/中的内容进行修改。

如上图所示,可以将脚本的名称复制到/root/bin目录中,这样就可以将该脚本的调用当成像命令一样了,或者直接将脚本的绝对目录加入到/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin中,这样对脚本的调用也可以像命令的调用一样了。

[root@localhost ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@localhost ~]#
 

对于脚本来说,如何给脚本加参数?

对于脚本来说,这个脚本的作用对象不同,给传递给脚本的参数也不相同。

在Linux操作系统中对参数的获取。这里的$数字参数,主要是位置参数。

如上图所示,当你想在调用脚本的时候,给脚本传递相应的参数的话,就需要在脚本中编写的时候,加入相应的变量来储存参数,比如$1这样的变量。

如上图所示,在编写脚本后记得给脚本添加上可执行权限,

script name:可以直接输出此时调用脚本的路径,

1st paramater :$1 这里的$1用来承接变量1

2nd paramater:$2这里的$2用来承接变量2

在Linux操作系统中对参数的获取,这里的$n参数,主要作用是统计系统传给脚本的参数的个数。

如上图所示,parameter numbers:2 表示当前系统传给脚本的参数个数是两个。

在Linux操作系统中对参数的获取,这里的$*和$@参数,$*的主要作用是代表命令行中所有的参数,$*把所有的参数看成是一个整体,$@把每个参数区分对待。

$*获取到的像是一个整体比如abc def

$@获取到的像是一个数组,比如[abc,def]  这里的$@获取到的结果像是一个数组,此时就可以使用循环去遍历里面的参数,

在Linux操作系统中对参数的获取,$?的作用是返回最后一次执行脚本的

$?这个特殊变量用来储存执行命令之后的返回值,如果返回值是0则表示上一条命令执行成功。

如上图所示,当一个命令执行成功的时候,此时敲命令 echo $?系统返回数字0表示命令执行成功,

当一个命令执行失败的时候,此时敲命令echo $?系统返回数字127表示命令执行失败。

注意在shell编程中使用单引号包围字符串和使用双引号包围字符串的时候有什么区别?

在Shell编程中,当你使用单引号(')包围字符串时,Shell会原样输出字符串内的内容,不做任何变量替换或特殊字符处理。所以,如果你写了 echo '======$n======',Shell会将$n视为字符串中的文字字符,而不是一个变量引用。它会原封不动地输出 ======$n=====, 而不会尝试去替换$n为它可能代表的变量值。

如果你想让Shell解析 $n 作为变量,并显示其值(假设之前已定义),你应该使用双引号("):

 

Bash

1echo "======$n======"

在双引号中,Shell会执行变量扩展、命令替换等操作,因此如果之前有定义变量 n,它的值就会被正确地插入到字符串中输出。

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

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

相关文章

Qt | QPalette 类(调色版)

01、简介 1、需要用到 QWidget类中的如下属性 palette:QPalette 访问函数:const QPalette &palette() const; void setPalette(const QPalette&);  该属性描述了部件的调色板。在渲染标准部件时,窗口部件的样式会使用调色板,而且不同的平台或不同的样式通常具…

win环境安装Node.js的多种方式

今天我们分享win环境安装Node.js的多种方式: 首先要明白Node.js是一个JavaScript运行环境,它基于Google的V8引擎进行封装,允许JavaScript运行在服务器端。Node.js让JavaScript成为一种与PHP、Python、Perl、Ruby等服务端语言平起平坐的脚本语…

图神经网络入门(1)-networkx

简介 NetworkX是一个Python语言的图论建模工具,用于创建、操作复杂网络结构(如图、有向图等)。它提供了许多用于分析网络、生成随机网络、以及可视化网络的函数和工具。用户可以利用NetworkX来研究复杂网络的拓扑结构、节点间的关系以及路径查…

【GIS案例】居住环境适宜性评价

目的: 拟购买住宅,需在现有条件下,基于地理空间分析方法和空间认知模型对居住环境进行综合评价。通过该实验掌握基于GIS的地理空间认知方法及土地适宜性评价基本原理与方法。 数据: (1)人口调查图(pop); (2)公园入口图(parkgate); (3)医院分布图(hospital…

【RK3588/算能/Nvidia智能盒子】挑战「无电无网」部署AI算法,守护大亚湾荃美石化码头工地安全

“万顷碧波之上,一座千米钢栈桥如蛟龙出水,向大海蜿蜒。钢栈桥上的项目建设者正在加紧作业,为助推惠州大亚湾加快建设成为世界级绿色石化基地全力奋战。”这是不久前北京日报对大亚湾惠州港荃湾港区荃美石化码头工地的描述。 △ 图片来源于北…

vue项目cnpm i 报错

报错内容: Install fail! TypeError: Cannot convert undefined or null to object npminstall version: 3.28.1 npminstall args: C:\Program Files\nodejs\node.exe C:\Users\user\AppData\Roaming\nvm\v12.4.0\node_modules\cnpm\node_modules\npminstall\bin\i…

序列化与反序列化漏洞实例

实验环境&#xff1a; 本次的序列化与反序列化漏洞为2021年强网杯上的一道比赛题目&#xff0c;我使用phpstudy集成环境将其测试环境搭建在了本地&#xff0c;如下。涉及的几个页面php为&#xff1a; index.php function.php myclass.php index.php : <?php // inde…

2024年阿里巴巴全球数学竞赛首次向人工智能(AI)开放

大家好&#xff0c;我是微学AI&#xff0c;最近大家突然开始关注阿里巴巴全球数学竞赛了&#xff0c;在这个人工智能爆发的时代&#xff0c;2024年阿里巴巴全球数学竞赛首次向人工智能&#xff08;AI&#xff09;开放&#xff0c;要求参赛的AI模型在比赛前提交源代码&#xff0…

数据上云--科技感满满

迁移上云&#xff1a;目的 1 为什么要上云 ① 公司发展规划&#xff0c;需要上云 如果我自己公司是自研的 ② 国家要求&#xff0c;第二&#xff1a;自研产品&#xff0c;但是公司不是纯靠销售来去盈利发展&#xff0c;而还会设计需要将我们的技术服务&#xff0c;提供给客户…

个人博客测试用例设计

个人博客测试用例设计 个人博客测试用例 分别从功能、性能、安全、兼容及界面分别展开 个人博客测试用例

【长春理工大学主办 | EI检索稳定 | SPIE出版 | 过往4届均检索 】第五届计算机视觉和数据挖掘国际学术会议(ICCVDM 2024)

第五届计算机视觉和数据挖掘国际学术会议&#xff08;ICCVDM 2024&#xff09; 2024 5th International Conference on Computer Vision and Data Mining 会议简介 第五届计算机视觉与数据挖掘国际学术会议&#xff08;ICCVDM 2024&#xff09;将于2024年7月19-21日在中国长春…

内部类介绍

内部类&#xff08;Inner Class&#xff09;是在另一个类的内部定义的类。它可以访问外部类的所有成员&#xff0c;包括私有成员。内部类有两种主要形式&#xff1a;局部内部类&#xff08;定义在方法内部&#xff09;和成员内部类&#xff08;定义在类的内部&#xff0c;但不在…

day02论文学习:能够使大语言模型产生带有引用的文章

1.主题&#xff1a;Enabling Large Language Models to Generate Text with Citations&#xff08;能够使大语言模型产生带有引用的文章&#xff09; 引用出处&#xff1a; Gao, T., Yen, H., Yu, J., & Chen, D. (2023). Enabling Large Language Models to Generate Tex…

PostgreSQL源码分析——CREATE SERVER

我们分析一下外部数据包装器中创建外部服务器的CREATE SERVER命令的实现源码。前面已经分析过很多DDL的语法实现。这里简单描述一下大致过程。 主流程如下所示&#xff1a; exec_simple_query(query_string); --> pg_parse_query(query_string);--> raw_parser(query_s…

Java基础 - 练习(二)打印菱形

Java基础练习 打印菱形&#xff0c;先上代码&#xff1a; // 方法一&#xff1a;基础&#xff0c;好理解 public static void diamond() {//控制行数for (int i 1; i < 4; i) {//空格的个数for (int k 1; k < 4 - i; k) {System.out.print(" ");}//控制星星…

使用Python连接MySQL数据库

1.导入包 import pymysql2.设置连接信息 pymsql中connect方法可以设置连接的信息 conn pymysql.connect(hostmHost, # 主机号port3306, # 端口号usermUser, # 用户名passwordmPwd, # 密码databasemDatabase # 数据库名称 )3.创建表 cursor()方法可以执行sql语句&…

如何构建构建一个AI驱动的通用爬虫

我最近开始研究网络爬虫&#xff0c;并且考虑到AI领域的一切发展&#xff0c;我认为尝试构建一个可以迭代导航网络直到找到它所寻找的内容的“通用”爬虫会很有趣。这是一个正在进行中的工作&#xff0c;但我想分享一下我目前的进展。 规格 给定一个起始URL和一个高级目标&…

vcruntime140_1.dll文件【安装包】【压缩包】【文件】【下载】

安装程序时有时候出现 类似无法启动程序&#xff0c;缺少vcruntime140_1.dll的提示&#xff0c;我们找到该文件并放到对应目录就可以&#xff1b;获取方法有很多&#xff0c;下面介绍两种&#xff1a;&#xff08;方法二更简便&#xff0c;不过建议两种方法都试试&#xff09; …

Swift开发——索引器扩展

扩展用于向已存在的类型(例如,类、结构体、枚举和协议等)中添加新的功能,扩展甚至可以向系统类型(包括无法查阅代码的类型)中添加新的功能,但是扩展不能覆盖原类型中已有的方法,扩展也不能向类中添加新的存储属性。 01、索引器扩展 扩展可为类、结构体等类型添加索引器。程序段…

golan的雪花id

今天记录一下 golang的雪花id golang的雪花id 还是比较简单的&#xff0c;其包含的含义以及组成我这就不讲了&#xff0c;好多大佬都有文章写过&#xff0c;我直接上怎么用 先 引入包 go get "github.com/bwmarrin/snowflake" 代码块 func main() {// 设置一个时…