Linux:Bash中变量的定义与使用

相关文章

Linux专栏https://blog.csdn.net/weixin_45791458/category_12234591.html


在bash shell中,变量(variable)是参数(parameter)的一类,用于存储值,且变量还可以拥有属性(attributes),这通过bash内建命令declare来完成。

一个存储空字符串的变量被看做是未设置(unset)的变量,可以通过bash内建命令unset将一个已设置的变量转化成未设置的。

给一个变量赋值可以通过下面的命令来完成。

复制代码
name=[value]

其中的name是一个合法的标识符,由数字、字母和下划线组成,且不能以数字开头。name后面必须紧跟=,不能有空格。如果有空格,则bash会将name解析成一个命令,而后面的=[value]解析为它的参数,这是一个错误。令人遗憾的是,即使用反斜杠\将空格转义,bash依然无法识别name =[value]这样的命令。[value]和=之间可以有空格,但这个空格必须被引号包围或反斜杠转义,否则空格之后的部分会被当做另一个命令名而不是value的一部分(这很有趣,在赋值命令后加其他命令不需要使用;分开,只需要使用空格分开)。value中如果有空格,则也需要使用引号包围或反斜杠转义,原因同理。下面展示了这些性质。

复制代码
例1
1a=test1   
bash: 1a=test1: command not found...  //错误,name不能以1开头,否则会被识别为命令名

a =test1
bash: a: command not found...         //错误,name和value之间不能有空格,否则name会被单独解析为一个命令名

a\ =test1                             
bash: a =test1: command not found...  //错误,即使转义空格,bash依旧识别不了这种格式

a= test1
bash: test1: command not found...     //错误,这会被解析为将空字符串赋值给a,并执行test1命令

a=\ test1   //bash可以解析这种格式的赋值
echo "$a"   //使用了双引号"",为的是打印出变量a的值中空格,否则其会被解析为分隔符                   
 test1      //前面有空格

a=" test1"  //bash可以解析这种格式的赋值
echo "$a"   //使用了双引号"",为的是打印出变量a的值中空格,否则其会被解析为分隔符                   
 test1      //前面有空格

a=te st1
bash: st: command not found...        //错误,st会被解析为另一个命令

a=test1 echo $a         //这是合法的,echo命令可以正常执行,而无需;分隔
test1

a="te st1"  //bash可以解析这种格式的赋值
echo "$a"   //使用了双引号"",为的是打印出变量a的值中空格,否则其会被解析为分隔符                   
te st1      //变量值中有空格

赋值命令中的value在使用前会首先进行拓展(实际上所有命令在解析前都会进行拓展,比如大括号拓展、波浪号拓展、参数(变量)拓展、命令替换、算数拓展、路径拓展等),在这里我们只涉及到简单的变量拓展,就是以name或{name}这种形式出现的拓展,它们两者的区别在于,后者更清晰的体现了变量名字的范围,而前者依赖bash解析到一个不合法的name字符从而确定name的范围。但需要注意的是,name在拓展后不会被解析为赋值语句,下面举例说明这些性质。

复制代码
例2
a=test1   //给a变量赋值test1
b=$a      //这条命令在执行前会先拓展为b=test1
echo $b   //这条命令在执行前会先拓展为echo test1
test1
b=$aa     //错误,变量拓展是贪婪的,这代表着bash会把aa解析为一个变量名($aa后的换行符不是合法的命名字符),而不是$a再加上a
b=${a}a   //这是正确的,因为{}明确指出了参数名的范围,所以参数拓展后为b=test1a
echo $b   //这条命令在执行前会先拓展为echo test1a
test1a
c=b      
$c=$a     //错误,即使name也使用了参数拓展,bash也无法识别这种形式的赋值语句
bash: b=test1: command not found...

例1中还使用了双引号"...",它使得其引用内容中的拓展正常进行(它不会使$失去作用,除此之外还有反引号`和某些条件下的转义符\),但它会使得其引用内容中的一些字符失去其特殊意义(空格、换行符等),只代表其字面意思,例如空格符,bash一般会将其当做分隔命令和其选项、参数的依据,而一个包含在双引号""内的空格符则只代表空格的字面意思。而单引号'...'的作用更加激进,它使得其引用内容的拓展也不进行,字符也都失去其特殊意义。

还有一个需要提到的是转义符\,它能使其后的任何一个字符失去其特殊意义(包括自己),当转义符被包括在双引号中,转义符在其后是$、`、"、\或换行符时保持其转义的能力,否则被当做字面量,例如其后紧跟着双引号或单引号的末尾,则双引号或单引号的末尾被转义,则此时后面还需要一个没有被转义的末尾来结束引用,简单来说就是,如果硬碰硬,则引号会被转义符打败。下面的例3说明了这些性质。

复制代码
例3
echo     hello world   //不使用引号,则其hello world前的空格都会被当做分隔符,最终echo获得两个参数hello和world
hello world
echo "   hello world"  //使用引号,则其hello world前的空格不会被当做分隔符,最终echo获得一个参数"   hello world"
   hello world
a=test1
echo "$a"              //双引号内的拓展可以正常进行,echo命令在执行前被拓展为echo "test1"
test1
echo '$a'              //单引号内的拓展不进行,echo命令为其字面意思echo '$a'
$a
echo "te'$a'st"        //双引号内可以直接嵌套单引号,此时单引号值表现其字面意思,因此$a的拓展可以进行,拓展为echo "te'test1'st"
te'test1'st
echo \$a               //转义符使$失去特殊意义,拓展不进行
$a
echo '$a'              //单引号使$失去特殊意义,拓展不进行
$a
echo "\$a"             //双引号本应使得转义符\失去特殊意义,但其后是$,因此转义符保持其转义能力$被转义,拓展不进行
$a
echo "\1"              //双引号本因转义符\失去特殊意义,只有字面意义
\1
相关推荐
a程序小傲2 分钟前
中国邮政Java面试被问:边缘计算的数据同步和计算卸载
java·服务器·开发语言·算法·面试·职场和发展·边缘计算
翼龙云_cloud5 分钟前
亚马逊云渠道商:如何在AWS控制台中创建每月成本预算?
服务器·云计算·aws
小尧嵌入式9 分钟前
【Linux开发二】数字反转|除数累加|差分数组|vector插入和访问|小数四舍五入及向上取整|矩阵逆置|基础文件IO|深入文件IO
linux·服务器·开发语言·c++·线性代数·算法·矩阵
试试勇气10 分钟前
Linux学习笔记(十二)--用户缓冲区
linux·笔记·学习
@小博的博客11 分钟前
Linux 中的编译器 GCC 的编译原理和使用详解
linux·运维·服务器
wdfk_prog13 分钟前
[Linux]学习笔记系列 -- [drivers][base]faux
linux·笔记·学习
ORBITVU13 分钟前
ORBITVU 自动化摄影眼镜360°展示解决方案
运维·自动化
骥龙14 分钟前
2.4下、固件安全分析与漏洞挖掘:从提取到逆向的完整实战指南
运维·物联网·安全
wheeldown15 分钟前
【Linux】TCP协议【2】: 从 echo 到远程命令执行:Linux TCP 服务器的并发与安全实践
linux·服务器·tcp/ip
衫水20 分钟前
Docker 常用指令大全(完整整合版)
运维·docker·容器