Shell变量类型和运算符

一、Shell变量类型

1、变量类型

Shell的3种变量:

(1)局部变量:除了本地变量外,还有shell脚本中定义的变量。

(2)全局变量:和局部变量相对。比如环境变量就是一种全局变量。

(3)特殊变量:shell内置的、具有特殊功能的变量。

  • 特殊参数变量:主要用于shell脚本中传递参数。
  • 特殊状态变量:主要用于查看命令状态的变量。

根据变量的作用域可以将 shell变量分为:全局变量、局部变量、环境变量,其中:

  • 局部变量:仅仅能在当前shell进程中使用,不能在当前shell的子shell中使用,更不能在其他shell中使用。
  • 全局变量:可以在当前shell进程及其子shell中使用。
  • 环境变量和全局变量通常划等号。

2、特殊变量

2.1 特殊参数变量

Shell特殊变量:主要用于传递参数的。

shell内置的特殊参数变量主要有:

在这里插入图片描述

Shell $*和$@之间的区别:

  • 当$* 和$@ 不被双引号""引住时,它们之间是没有任何区别的,都是将接收到的每个参数看做一份数据,彼此之间以空格来分隔。
  • 当$* 和$@ 被双引号"“引住时,”$*" 会将所有的参数从整体上看作一份数据,而不是把每个参数都看作一份数据。也就是参数之间是无法分隔的,因为是一份数据嘛。而"$@" 依然是将每个参数都看作一份数据,彼此之间是独立的,就是有参数个数份数据。

所以当我们echo $* 和 echo$@时,看不出什么区别,但是当我们使用for循环逐个输出数据时,区别就出来了。

2.1 特殊状态变量

shell内置的特殊状态变量主要有:

在这里插入图片描述

二、Shell变量类型

Shell 支持不同类型的变量,下面是一些最常用的数据类型。

1、字符串变量

字符串(String)就是一系列字符的组合。字符串是 Shell 编程中最常用的数据类型之一。

字符串可以由单引号’ '包围,也可以由双引号" "包围,也可以不用引号。它们之间是有区别的。

三种形式的区别:

(1) 由单引号’ '包围的字符串

  • 单引号里的任何字符都会原样输出,在其中使用的变量是无效的。
  • 单引号字串中不能出现单独一个的单引号(即使对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用。

(2) 由双引号" "包围的字符串

  • 双引号里可以包含变量,该变量会被解析(得到该变量的值),而不是原样输出。
  • 双引号里可以出现转义字符,比如双引号,只要它被转义了就行。

(3) 不被引号包围的字符串

  • 不被引号包围的字符串中出现变量时也会被解析,这一点和双引号" "包围的字符串一样。
  • 字符串中不能出现空格,否则空格后边的字符串会作为其他变量或者命令解析。对于不连续的字符串最好使用双引号。

1.1 字符串拼接

在脚本语言中,字符串的拼接(也称字符串连接或者字符串合并)往往都非常简单。

在 Shell 中你不需要使用任何运算符,将两个字符串并排放在一起就能实现拼接,非常简单粗暴。

示例如下:

#!/bin/bashname="Shell"
url="http://www.baidu.com"str1=$name$url  #中间不能有空格
str2="$name $url"  #如果被双引号包围,那么中间可以有空格
str3=$name": "$url  #中间可以出现别的字符串
str4="$name: $url"  #这样写也可以
str5="${name}Script: ${url}index.html"  #这个时候需要给变量名加上大括号echo $str1
echo $str2
echo $str3
echo $str4
echo $str5

在这里插入图片描述

1.2 获取字符串长度

在 Shell 中,通过 ${#string_name} 来获取字符串长度。

示例如下:

#!/bin/bashurl="http://www.baidu.com"
echo ${#url}   # 20
# 变量为字符串时,${#string_name} 等价于 ${#string_name[0]}
echo ${#url[0]} # 20

1.3 字符串字符串截取

Shell 截取字符串通常有两种方式:从指定位置开始截取和从指定字符(子字符串)开始截取。

1.3.1 从指定位置开始截取

这种方式需要两个参数:除了指定起始位置,还需要截取长度,才能最终确定要截取的字符串。

指定起始位置时,可以从字符串左边开始计数,也可以从字符串右边开始计数。

(1) 从字符串左边开始计数

从字符串的左边开始计数,格式如下:${string: start :length}

其中:

  • string 是要截取的字符串,
  • start 是起始位置(从左边开始,从 0 开始计数),
  • length 是要截取的长度(省略的话表示直到字符串的末尾)。

示例如下:

#!/bin/bashurl="http://www.baidu.com"echo ${url: 2: 9}
echo ${url: 3}  #省略 length,截取到字符串末尾

在这里插入图片描述

(2)从右边开始计数

从字符串的右边开始计数,格式如下:${string: 0-start :length}

格式中多了0-,这是固定的写法,专门用来表示从字符串右边开始计数。

需要注意:

  • 从左边开始计数时,起始数字是 0(这符合程序员思维);从右边开始计数时,起始数字是 1(这符合常人思维)。计数方向不同,起始数字也不同。
  • 不管从哪边开始计数,截取方向都是从左到右。

示例如下:

#!/bin/bashurl="http://www.baidu.com"echo ${url: 0-13: 9}
echo ${url: 0-13}  #省略 length,直接截取到字符串末尾

在这里插入图片描述

1.3.2 从指定字符(子字符串)开始截取

这种截取方式无法指定字符串长度,只能从指定字符(子字符串)截取到字符串末尾。

Shell 可以截取指定字符(子字符串)右边的所有字符,也可以截取左边的所有字符。

(1)使用 # 号截取右边字符

使用#号可以截取指定字符(或者子字符串)右边的所有字符,格式如下:${string#*chars}

其中:

  • string 表示要截取的字符,
  • chars 是指定的字符(或者子字符串),*是通配符的一种,表示任意长度的字符串。*chars连起来

使用的意思是:忽略左边的所有字符,直到遇见 chars(chars 不会被截取)。

示例如下:

#!/bin/bashurl="http://www.baidu.com"echo ${url#*:}
echo ${url#*p:}
echo ${url#*ttp:}

在这里插入图片描述

如果不需要忽略 chars 左边的字符,那么也可以不写*。

示例如下:

#!/bin/bashurl="http://www.baidu.com"echo ${url#http://}
echo ${url#*/}

在这里插入图片描述

注意:以上写法遇到第一个匹配的字符(子字符串)就结束了。

如果希望直到最后一个指定字符(子字符串)再匹配结束,那么可以使用##,格式为:${string##*chars}

示例如下:

#!/bin/bashurl="http://www.baidu.com"
url="http://c.biancheng.net/index.html"echo ${url#*/}    #结果为 /c.biancheng.net/index.html
echo ${url##*/}   #结果为 index.html
str="---aa+++aa@@@"
echo ${str#*aa}   #结果为 +++aa@@@
echo ${str##*aa}  #结果为 @@@

(2)使用 % 截取左边字符

使用%号可以截取指定字符(或者子字符串)左边的所有字符,格式如下:${string%chars*}

注意*的位置,因为要截取 chars 左边的字符,而忽略 chars 右边的字符,所以*应该位于 chars 的右侧。

示例如下:

#!/bin/bashurl="http://www.baidu.com"
url="http://c.biancheng.net/index.html"
echo ${url%/*}  #结果为 http://c.biancheng.net
echo ${url%%/*}  #结果为 http:
str="---aa+++aa@@@"
echo ${str%aa*}  #结果为 ---aa+++
echo ${str%%aa*}  #结果为 ---

2、整数变量

在一些Shell中,你可以使用 declare 或 typeset 命令来声明整数变量。这样的变量只包含整数值。

示例如下:

#!/bin/bashdeclare -i my_integer=42
echo ${my_integer}
my_integer=hello
echo ${my_integer}

这样的声明告诉 Shell 将 my_integer 视为整数,如果尝试将非整数值赋给它,Shell会尝试将其转换为整数。

在这里插入图片描述

3、数组变量

数组(Array)是若干数据的集合,其中的每一份数据都称为元素(Element)。

Bash Shell 只支持一维数组(不支持多维数组),并且没有限制数组的大小,理论上可以存放无限量的数据。

Shell 数组元素的下标也是从 0 开始计数。获取数组中的元素要使用下标[ ],下标可以是一个整数,也可以是一个结果为整数的表达式0。

3.1 定义数组

在 Shell 中,用括号 ( ) 来表示数组,数组元素之间用空格来分隔。

定义数组的一般形式为:array_name=(ele1 ele2 ele3 … elen)

注意:

  • 赋值号=两边不能有空格,必须紧挨着数组名和数组元素。
  • Shell 是弱类型的,它并不要求所有数组元素的类型必须相同。

示例如下:

#!/bin/bashnums=(29 100 13 8 91 44)
arr=(20 56 "http://www.baidu.com")# 定义之后还可以增加元素
nums[6]=88# 无需逐个元素地给数组赋值,我们也可以只给特定元素赋值
ages=([3]=24 [5]=19 [10]=12) # 只给第 3、5、10 个元素赋值,所以数组长度是 3。

3.2 获取数组的长度

数组长度,就是数组元素的个数。

利用 @或 *,可以将数组扩展成列表,然后使用 #来获取数组元素的个数,格式如下:
${#array_name[@]}
${#array_name[*]}

其中 array_name 表示数组名。两种形式是等价的,选择一种即可。

如果某个元素是字符串,还可以通过指定下标的方式获得该元素的长度。其实获取数组长度的方法与获取字符串长度的方法如出一辙。

示例如下:

#!/bin/basharr=(20 56 "http://www.baidu.com")
echo ${#arr[*]}    # 输出 3
echo ${#arr[@]}   # 输出 3
echo ${#arr[2]}    # 输出 20#向数组中添加元素
arr[10]="ele88"echo ${#arr[*]}   # 输出 4
echo ${#arr[10]}  # 输出 5#删除数组元素
unset arr[1]      
echo ${#arr[*]}   # 输出 3

3.3 读取数组元素

(1)获取数组中某个元素的值。

一般格式为:${array_name[index]}

其中,array_name 是数组名,index 是下标。

(2)使用 @或 *可以获取数组中的所有元素。

一般格式为:

${array_name[*]}
${array_name[@]}

两者都可以得到 array_name 数组的所有元素。

示例如下:

#!/bin/bashnums=(29 100 13 8 91 44)
echo ${nums[@]}  #输出所有数组元素nums[10]=66  #给第10个元素赋值(此时会增加数组长度)
echo ${nums[*]}  #输出所有数组元素
echo ${nums[4]}  #输出第5个元素

在这里插入图片描述

三、Shell运算符

Shell 和其他编程语言一样,支持多种运算符,包括:

  • 算数运算符
  • 关系运算符
  • 布尔运算符
  • 字符串运算符
  • 文件测试运算符

原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。

基本语法:

方式1:value=$((运算式))
方式2:value=$[运算式]
方式3:value=`expr m + n`

expr(expression的缩写)是一款表达式计算工具,使用它能完成表达式的求值操作。

使用expr时注意:

  • 表达式和运算符之间要有空格。
  • 完整的表达式要被要被 反引号包含,这个字符不是常用的单引号,在 Esc 键下边。
  • expr +,-,*,/,% <==> 加,减,乘,除,取余

1、算术运算符

下表列出了常用的算术运算符,假定变量 a 为 10,变量 b 为 20:

在这里插入图片描述

注意:条件表达式要放在方括号之间,并且要有空格,例如: [$a==$b] 是错误的,必须写成 [ $a == $b ]。

示例如下:

#!/bin/bashres1=$(((2+3)*4))
res2=$[(2+3)*5]
temp=`expr 2 + 3`
res3=`expr ${temp} \* 6`echo "res1=${res1}"
echo "res2=${res2}"
echo "temp=${temp}"
echo "res3=${res3}"a=10
b=20val=`expr $a + $b`
echo "a + b = : $val"if [ $a == $b ]
thenecho "a 等于 b"
fi
if [ $a != $b ]
thenecho "a 不等于 b"
fi

在这里插入图片描述

2、关系运算符

关系运算符只支持数字,不支持字符串,除非字符串的值是数字。

下表列出了常用的关系运算符,假定变量 a 为 10,变量 b 为 20:

在这里插入图片描述

示例如下:

#!/bin/basha=10
b=20if [ $a -eq $b ]
thenecho "$a -eq $b : a 等于 b"
elseecho "$a -eq $b: a 不等于 b"
fiif [ $a -ge $b ]
thenecho "$a -ge $b: a 大于或等于 b"
elseecho "$a -ge $b: a 小于 b"
fi

在这里插入图片描述

3、布尔运算符

下表列出了常用的布尔运算符,假定变量 a 为 10,变量 b 为 20:

在这里插入图片描述

示例如下:

#!/bin/bashres1=$((2 != 3))
echo "res1=${res1}"a=10
b=20if [ $a != $b ]
thenecho "$a != $b : a 不等于 b"
elseecho "$a == $b: a 等于 b"
fiif [ $a -lt 100 -a $b -gt 15 ]
thenecho "$a 小于 100 且 $b 大于 15 : 返回 true"
elseecho "$a 小于 100 且 $b 大于 15 : 返回 false"
fiif [ $a -lt 100 -o $b -gt 100 ]
thenecho "$a 小于 100 或 $b 大于 100 : 返回 true"
elseecho "$a 小于 100 或 $b 大于 100 : 返回 false"
fi

在这里插入图片描述

4、逻辑运算符

以下介绍 Shell 的逻辑运算符,假定变量 a 为 10,变量 b 为 20:

在这里插入图片描述

示例如下:

#!/bin/basha=10
b=20if [[ $a -lt 100 && $b -gt 100 ]]
thenecho "返回 true"
elseecho "返回 false"
fiif [[ $a -lt 100 || $b -gt 100 ]]
thenecho "返回 true"
elseecho "返回 false"
fi

在这里插入图片描述

5、字符串运算符

下表列出了常用的字符串运算符,假定变量 a 为 “abc”,变量 b 为 “efg”:

在这里插入图片描述

示例如下:

#!/bin/basha="abc"
b="efg"if [ $a = $b ]
thenecho "$a = $b : a 等于 b"
elseecho "$a = $b: a 不等于 b"
fiif [ $a != $b ]
thenecho "$a != $b : a 不等于 b"
elseecho "$a != $b: a 等于 b"
fiif [ -z $a ]
thenecho "-z $a : 字符串长度为 0"
elseecho "-z $a : 字符串长度不为 0"
fiif [ -n "$a" ]
thenecho "-n $a : 字符串长度不为 0"
elseecho "-n $a : 字符串长度为 0"
fiif [ $a ]
thenecho "$a : 字符串不为空"
elseecho "$a : 字符串为空"
fi

在这里插入图片描述

参考文章:

  • 菜鸟教程-Shell 基本运算符:https://www.runoob.com/linux/linux-shell-basic-operators.html

– 求知若饥,虚心若愚。

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

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

相关文章

MaxScale实现mysql8读写分离

MaxScale 实验环境 中间件192.168.150.24MaxScale 22.08.4主服务器192.168.150.21mysql 8.0.30从服务器192.168.150.22mysql 8.0.30从服务器192.168.150.23mysql 8.0.30 读写分离基于主从同步 1.先实现数据库主从同步 基于gtid的主从同步配置 主库配置 # tail -3 /etc/my.…

刷新多个SOTA!最新Mamba魔改版本超越transformer,GPU内存消耗减少74%

因模型规模的扩展和需要处理的序列不断变长&#xff0c;transformer逐渐出现计算量激增、计算效率下降等问题。为克服这些缺陷&#xff0c;研究者们提出了Mamba。 Mamba是一种创新的线性时间序列建模方法&#xff0c;它结合了递归神经网络&#xff08;RNN&#xff09;和卷积神…

[面试] InnoDB中如何解决幻读?

幻读是通过 MVCC 机制来解决的, MVCC 类似于一种乐观锁的机制&#xff0c;通过版本的方式来区分不同的并发事务&#xff0c;避免幻读 问题! 什么是幻读? 事务A前后两次读取同一个范围的数据&#xff0c;在事务A两次读取的过程之间&#xff0c;事务B新增了数据&#xff0c;导致…

星际修仙之剑胆琴心

剧名&#xff1a;《星际修仙之剑胆琴心》 类型&#xff1a;科幻修仙爱情剧 故事大纲&#xff1a; 在遥远的未来&#xff0c;人类文明已经发展到星际时代&#xff0c;科技与修仙相结合&#xff0c;形成了一种全新的文明形态。在这个时代&#xff0c;修仙者不再局限于传统的修炼方…

图文说明Linux云服务器如何更改实例镜像

一、应用场景举例 在学习Linux的vim时&#xff0c;我们难免要对vim进行一些配置&#xff0c;这里我们提供一个vim插件的安装包&#xff1a; curl -sLf https://gitee.com/HGtz2222/VimForCpp/raw/master/install.sh -o./install.sh && bash ./install.sh 但是此安装包…

跳槽前应该做好哪些准备?

第一次求职也好&#xff0c;还是换工作也罢&#xff0c;都需要有严谨的考虑。对于已经工作上班的朋友来说&#xff0c;切不可轻易地辞掉工作&#xff0c;想要跳槽&#xff0c;一定要三思而后行&#xff0c;有一个周密的部署。跳槽有好处&#xff0c;也有弊端&#xff0c;频繁的…

【学网攻】 第(30)节 -- 综合实验三

系列文章目录 目录 系列文章目录 文章目录 前言 一、综合实验 二、实验 1.引入 实验目标 实验设备 实验拓扑图 实验配置 文章目录 【学网攻】 第(1)节 -- 认识网络【学网攻】 第(2)节 -- 交换机认识及使用【学网攻】 第(3)节 -- 交换机配置聚合端口【学网攻】 第(4)节…

探讨导致vcruntime140_1.dll无法继续执行代码的原因和解决办法

在使用电脑过程中&#xff0c;我们偶尔会遇到一些令人不悦的错误提示&#xff0c;如"vcruntime140_1.dll丢失"。这个错误提示可能会给我们带来诸多困扰&#xff0c;阻碍我们正常地进行操作。本文将详细探讨导致"vcruntime140_1.dll丢失"错误的原因&#xf…

Java基于SSM+JSP的超市进销库存管理系统

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

开源图表库Echarts 简介与基本使用

ECharts 是一个使用 JavaScript 实现的开源可视化图表库&#xff0c;由百度团队开发。它提供了丰富的图表类型&#xff0c;如折线图、柱状图、饼图、地图、雷达图等&#xff0c;并且可以轻松地与其他前端框架和库集成。ECharts 的设计目的是为了满足复杂数据的可视化需求&#…

flutter开发实战-StreamBuilder使用介绍及实例

flutter开发实战-StreamBuilder使用介绍及实例 StreamBuilder是一个Widget&#xff0c;它依赖Stream来做异步数据获取刷新widget。 一、Stream Stream是一种用于异步处理数据流的机制&#xff0c;它允许我们从一段发射一个事件&#xff0c;从另外一段去监听事件的变化.Strea…

Leetcode3035. 回文字符串的最大数量

Every day a Leetcode 题目来源&#xff1a;3035. 回文字符串的最大数量 解法1&#xff1a;哈希 排序 由于可以随意交换字母&#xff0c;先把所有字母都取出来&#xff0c;然后考虑如何填入各个字符串。 如果一个奇数长度字符串最终是回文串&#xff0c;那么它正中间的那…

精美的WordPress外贸独立站模板

WordPress外贸独立站主题 简洁实用的WordPress外贸独立站主题&#xff0c;适合时尚服装行业搭建wordpress企业官网使用。 https://www.jianzhanpress.com/?p4999 简洁wordpress独立站模板 绿色精美、简洁大气的wordpress外贸独立网站模板 https://www.jianzhanpress.com/?…

分享一个UE的SmoothStep小技巧

SmoothStep节点可以制作更平滑的动画&#xff0c;而如果将max参数作为值传入将value和min参数作为约束&#xff0c;则可以做出类似冲击波的渐变效果&#xff1a; 并且通过修改value与min之间的数值差&#xff0c;可以调节渐变。 这个技巧主要就是可以产生硬边。 比如我们可…

【黑马程序员】C++模版

20240214 文章目录 C泛型编程技术模版的概念 函数模版函数模版语法不使用模版的模版完成两个数交换使用模版的方式完成两个数的交换模版注意事项函数模版案列使用模版实现升序选择排序 模版函数和普通函数区别点调用规则 模版的局限性模版的通用性问题模版重载 类模板类模板语…

Redis和Mysql如何保证数据一致性

一般情况下&#xff0c;Redis用来实现应用和数据库之间读操作的缓存层&#xff0c;主要目的是减少数据 库IO&#xff0c;还可以提升数据的IO性能。 这是它的整体架构。 当应用程序需要去读取某个数据的时候&#xff0c;首先会先尝试去Redis里面加载&#xff0c;如果命中就 直…

【Java程序员面试专栏 数据结构】一 高频面试算法题:数组

一轮的算法训练完成后,对相关的题目有了一个初步理解了,接下来进行专题训练,以下这些题目就是汇总的高频题目,本篇主要聊聊数组,包括数组合并,滑动窗口解决最长无重复子数组问题,图形法解下一个排列问题,以及一些常见的二维矩阵问题,所以放到一篇Blog中集中练习 题目…

k8s(3)

目录 一.K8S的三种网络 flannel的三种模式: 在 node01 节点上操作&#xff1a; calico的 三种模式&#xff1a; flannel 与 calico 的区别&#xff1f; 二.CoreDNS 在所有 node 节点上操作&#xff1a; 在 master01 节点上操作&#xff1a; ​编辑 DNS 解析测试&#…

「C语言进阶1」动态内存分配

目录 一、动态内存分配是什么&#xff1f; 二、为什么需要动态内存分配&#xff1f; 三、怎么进行动态内存分配&#xff1f; 1. malloc 2. calloc 3. realloc a. realloc功能解析 b. 内存泄漏和内存块被截断问题 c. 总结 4. free 四、使用动态内存分配常见的问题 【面试题】 一…

如何将新标注的三元组数据转换成unicoqe可以处理的格式

目录 问题描述&#xff1a; 问题解决&#xff1a; 问题描述&#xff1a; 原始的标注的三元组格式如下&#xff1a; 需要转换的格式如下&#xff1a; tips:有一个小的难点&#xff1a; 1. 针对多三元组的情况&#xff0c;需要额外考虑 2. 最后一个样本&#xff0c;也记得需要…