当前位置:   article > 正文

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

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

  相关文章

Linux专栏icon-default.png?t=N7T8https://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. 1
  2. 1a=test1
  3. bash: 1a=test1: command not found... //错误,name不能以1开头,否则会被识别为命令名
  4. a =test1
  5. bash: a: command not found... //错误,name和value之间不能有空格,否则name会被单独解析为一个命令名
  6. a\ =test1
  7. bash: a =test1: command not found... //错误,即使转义空格,bash依旧识别不了这种格式
  8. a= test1
  9. bash: test1: command not found... //错误,这会被解析为将空字符串赋值给a,并执行test1命令
  10. a=\ test1 //bash可以解析这种格式的赋值
  11. echo "$a" //使用了双引号"",为的是打印出变量a的值中空格,否则其会被解析为分隔符
  12. test1 //前面有空格
  13. a=" test1" //bash可以解析这种格式的赋值
  14. echo "$a" //使用了双引号"",为的是打印出变量a的值中空格,否则其会被解析为分隔符
  15. test1 //前面有空格
  16. a=te st1
  17. bash: st: command not found... //错误,st会被解析为另一个命令
  18. a=test1 echo $a //这是合法的,echo命令可以正常执行,而无需;分隔
  19. test1
  20. a="te st1" //bash可以解析这种格式的赋值
  21. echo "$a" //使用了双引号"",为的是打印出变量a的值中空格,否则其会被解析为分隔符
  22. te st1 //变量值中有空格

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

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

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

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

  1. 3
  2. echo hello world //不使用引号,则其hello world前的空格都会被当做分隔符,最终echo获得两个参数hello和world
  3. hello world
  4. echo " hello world" //使用引号,则其hello world前的空格不会被当做分隔符,最终echo获得一个参数" hello world"
  5. hello world
  6. a=test1
  7. echo "$a" //双引号内的拓展可以正常进行,echo命令在执行前被拓展为echo "test1"
  8. test1
  9. echo '$a' //单引号内的拓展不进行,echo命令为其字面意思echo '$a'
  10. $a
  11. echo "te'$a'st" //双引号内可以直接嵌套单引号,此时单引号值表现其字面意思,因此$a的拓展可以进行,拓展为echo "te'test1'st"
  12. te'test1'st
  13. echo \$a //转义符使$失去特殊意义,拓展不进行
  14. $a
  15. echo '$a' //单引号使$失去特殊意义,拓展不进行
  16. $a
  17. echo "\$a" //双引号本应使得转义符\失去特殊意义,但其后是$,因此转义符保持其转义能力$被转义,拓展不进行
  18. $a
  19. echo "\1" //双引号本因转义符\失去特殊意义,只有字面意义
  20. \1

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号