搞懂Linux Shell中的变量

如何在Bash中合理的设置变量

    • Bash中变量的设置
    • 环境变量和自定义变量
      • 几个重要的环境变量
      • 从键盘获取变量的值
      • 定义变量declare
    • 变量内容的变更
      • 变量内容的删除
      • 变量内容的替换
      • 变量的默认值替换设置
      • 更多的变量替换设置方式

Bash中变量的设置

  1. 变量与变量内容以一个等号“=”来连接;
    variable=ABC

  2. 等号两边不能直接接空格;

  3. 变量名称只能是英文字母与数字组合,且开头字符不能是数字

  4. 变量内容如果有空格符,可以使用双引号或者单引号将变量内容包起来;
    variable="I like you"

  5. 双引号包起来的变量内容和单引号包起来的变量内容有一些区别,双引号内的特殊字符如 $ 等可以保有原来的特性; 单引号内的特殊字符则只能为一般字符;
    variable1="language is $LANG"
    variable2='language is $LANG'
    如果显示变量 echo $variable1 ,则会得到:
    "language is en_US"
    如果显示变量 echo $variable2 ,则会得到:
    'language is $LANG'

  6. 可以使用转义符号“\”将特殊符号如[Enter]、$、\ 、空格符等变成一般的字符;

  7. 在一串命令中,如果还需要通过其他命令提供的信息,可以使用反单引号(数字1左边 的那个键)“`命令`”或“$(命令)”;

version=`uname -r`
echo version		# 可以得到当前系统内核的版本号,如我的就是“5.7.4-arch1-1”
version=$(uname -r)
echo version	# 这两种方法是相同的,得到的结果一样
  1. 如果你想给一个变量累加变量内容时,可以使用“"$变量名称"”或“${变量名称}”累加内容,如我们想在上面的version这个变量中后面再追加一些内容;
    version="$version"hahahahah
    这时,变量就会在后面累加“hahahahah”
    echo $version
    会得到:“5.7.4-arch1-1hahahahah”
    version=${version}hahahahah 是一样的效果
    值得注意的一点是,PATH这个变量比较特殊,在累加路径的时候,不加双引号也是可以的,如
    PATH=$PATH:/home/bin
    PATH=${PATH}:/home/bin
    PATH=$"PATH":/home/bin
    都可以在原本的变量内容后面累加自定义内容。
  2. 如果该变量需要在其他子进程中执行,则需要以export来使变量变成环境变量;
    export PATH
    如果没有这一步,那么定义的变量就只能在当前这个shell中使用,在该shell的子进程(在当前shell下,打开一个新的shell,那么那个新的shell就是当前shell的子进程)中就无法使用,但是通过export命令可以将该变量变为环境变量,这样的话,子进程也就可以使用当前shell定义的变量了。
  3. 通常大写字符为系统默认变量,自行设置的变量可以使用小写字符,方便判断,当然,这个是习惯问题,你也喜欢大写,也无伤大雅;
  4. 取消变量的方法是使用“unset 变量名称”,例如取消上面的version变量:
    unset version
    取消变量的设置之后,你再echo显示的话,发现version这个变量已经是个空的了。

环境变量和自定义变量

通过 env 这个命令来查看当前运行环境的环境变量,它会列出所有的环境变量。
通过 set 这个命令来查看所有的变量,它会列出环境变量和自定义变量。
通过 export 将自定义变量变为环境变量,也就是子进程可以用的变量。

几个重要的环境变量

变量名 代表的含义
HOME 代表当前用户的主文件夹
SHELL 当前这个操作环境使用的shell,Linux默认是/bin/bash
HISTSIZE 命令执行历史记录条目数
MAIL 当前用户的邮件信箱文件夹路径
PATH 执行文件查找路径,目录间以冒号分隔
LANG 语系数据,也就是终端显示的语言编码相关的内容
RANDOM 随机数生成器,生成0~32768之间的一个随机数

[小案例] 生成一个0~9之间的随机数怎么搞?

# 使用declare来声明数值类型
declare -i number=$RANDOM*10/32768 ; ehco $number

从键盘获取变量的值

read命令
-p 后面引号内接提示信息
-t 后面接时间,单位秒,等待时间到了之后,进行下一步操作,不会长时间等待用户

定义变量declare

declare 的几个参数
-:给变量设置类型属性
+:取消变量的类型属性
-a: 将变量定义为数组类型(array)
-i: 将变量定义为整数数字类型(integer)
-r: 将变量定义为只读类型,不可更改内容,也不能重设
-x: 将变量定义为环境变量

变量内容的变更

变量内容的删除

变量内容的删除分为从前往后删除和从后往前删除; 其中,从前往后删除有两种情况:

  1. 从头删除到第一个匹配项 ${变量名#要删除的部分}
  2. 从头删除到最后一个匹配项 ${变量名##要删除的部分}
    所以两者的区别就是一个“#”和两个“#”。

案例:

# 先获取我们的PATH变量到一个我们的自定义变量,毕竟PATH这个变量不能随便改
abc=${PATH}
echo $abc
/root/.gem/ruby/2.6.0/bin:/opt/nvim-linux64/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl
# 从头开始删除,一直到第一个匹配项
echo ${abc#/*bin:}
/opt/nvim-linux64/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl
# 看,删除了 /root/.gem/ruby/2.6.0/bin: 
# 从头开始删除,一直到最后一个匹配项
echo ${abc##/*bin:}
/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl
# 看,删除了/root/.gem/ruby/2.6.0/bin:/opt/nvim-linux64/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:

从后往前删除也分为两种情况,跟前面的从前往后删除是一样的道理:

  1. 从头删除到第一个匹配项 ${变量名%要删除的部分}
  2. 从头删除到最后一个匹配项 ${变量名%%要删除的部分}
    所以两者的区别就是一个“%”和两个“%”。

案例:

# 先获取我们的PATH变量到一个我们的自定义变量,毕竟PATH这个变量不能随便改
abc=${PATH}
echo $abc
/root/.gem/ruby/2.6.0/bin:/opt/nvim-linux64/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl
# 从后往前删除,且只删除到第一个匹配项
echo ${abc%:/*bin*}
/root/.gem/ruby/2.6.0/bin:/opt/nvim-linux64/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl
# 看,删除了:/usr/bin/core_perl
echo ${abc%%:/*bin*}
/root/.gem/ruby/2.6.0/bin
# 看,删除了:/opt/nvim-linux64/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl

变量内容的替换

变量内容的替换主要是由“/”这个符号来完成的。
共分为两种情况,一种是替换从左往右第一个匹配项,另一种是替换所有的匹配项:

  1. 从左往右替换第一个匹配项 ${变量名/匹配项(旧内容)/要替换成的新内容}
  2. 从头删除到最后一个匹配项 ${变量名//匹配项(旧内容)/要替换成的新内容}
    所以两者的区别就是一个“/”和两个“/”。

案例:

# 先获取我们的PATH变量到一个我们的自定义变量,毕竟PATH这个变量不能随便改
abc=${PATH}
echo $abc
/root/.gem/ruby/2.6.0/bin:/opt/nvim-linux64/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl
# 替换第一个匹配项
echo ${abc/bin/BIN}
/root/.gem/ruby/2.6.0/BIN:/opt/nvim-linux64/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl
# 看,只有第一个bin被替换为了大写的BIN
# 替换所有的bin为BIN
echo ${abc//bin/BIN}
/root/.gem/ruby/2.6.0/BIN:/opt/nvim-linux64/BIN:/usr/local/sBIN:/usr/local/BIN:/usr/BIN:/usr/lib/jvm/default/BIN:/usr/BIN/site_perl:/usr/BIN/vendor_perl:/usr/BIN/core_perl
# 看,所有的bin都被替换为了大写的BIN

变量的默认值替换设置

有些情况下,在给一个变量赋值时,需要先判断该变量是否存在,或者该变量是否已经被设置为了空字符串。

  1. 判断该变量是否还未设置,如果还未设置就赋给默认值
    变量名=${变量名-默认值}
  2. 判断该变量是否还未设置或者已经被设置为了空字符串,如果符合以上两种情况就给其设置默认值。
    变量名=${变量名:-默认值}
    第二种虽然只是在“-”号前面多了一个冒号“:”,但是两者的区别还是相当大的,所以要结合实际情况使用。

案例:

echo $aname
			#输出空行,因为aname没有被设置过
aname=${aname-goodguy}
echo $aname
goodguy
# 看,由于aname是未设置的空变量,所以它被设置了制定的默认值
# bname已经被设置了值,即它不是空的变量
bname=badguy
echo $bname
badguy
bname=${bname-goodguy}	# 设置如果bname为空变量,则默认值为goodguy
echo $bname
badguy
# 看,因为bname已经被设置了badguy这个值,所以默认值不会生效。
# 但是,上面的情况,aname被赋予默认值是因为aname没有被设置,而当你echo aname时显示
# 空行的话,还有一种情况,那就是aname被赋予了空字符串,即aname="",这种情况下,使用上面的
# 方法是无法给aname赋予默认值的,因为系统认为aname被设置过了。
# 这个时候,就需要“:”出场了。
cname=""
# cname被设置为了空字符串
echo $cname
	# 显示空行,因为cname是空字符串,是看不见的
cname=${cname-goodguy}	# 使用上面的方法赋值
echo $cname
	# 还是显示空行,因为上面的方法无法给已经设置了空字符串的变量赋予默认值
# 再来试试第二个方法
cname=${cname:-goodguy}
echo $cname
goodguy
# 看,cname被成功的赋予了默认的值,即使它已经被赋予了一个空的字符串

更多的变量替换设置方式

变量的设置方式 str没有设置 str为空字符串 str已设置为非空字符串
var=${str-xxx} var=xxx var= var=$str
var=${str:-xxx} var=xxx var=xxx var=$str
var=${str+xxx} var= var=xxx var=xxx
var=${str:+xxx} var= var= var=xxx
var=${str=xxx} str=xxx; var=xxx str不变; var= str不变; var=$str
var=${str:=xxx} str=xxx; var=xxx str=xxx; var=xxx str不变; var=$str
var=${str?xxx} xxx输出到stderr var= var=str
var=${str:?xxx} xxx输出到stderr xxx输出到stderr var=str

你可能感兴趣的:(Linux)