Shell 中的变量

146 阅读3分钟

Shell 的变量功能

什么是变量

变量是编程中的一个抽象概念,变量是对内存空间的一个引用,能够通过变量访问对应的数值,这个数值就是我们关心的数据。变量名引用的内存空间是可变的,引用的空间内的数值也是可变的,所以表现出一种固定字符串代表的值可变这样一种现象。

某些变量会影响到 bash 环境,用户真正在 shell 平台上操作应用程序与 Linux 沟通,是在正确登录 Linux 之后,这时用户就拥有一个 bash 的执行程序,而在取得 shell 之前的过程中,系统需要一些变量来支持它数据(环境的设定参数值)的存取,所以就有一些所谓的环境变量需要读到系统中了,例如:PATH、HOME、MAIL、SHELL 等,为了区别环境变量和自定义变量的不同,环境变量通常使用大写字符来表示

变量的取用与设定

变量的取用:echo

[root@study ~]# echo $variable
[root@study ~]# echo $PATH
/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin
[root@study ~]# echo ${PATH} #同样可以使用这样的方式

变量的取用需要在变量前面加上 $,或者是以 ${变量} 这种方式来取用变量值。

使用【等号(=)】来设定和修改变量的值,下面将 myname 这个变量设定变量值为 VBird

[root@study ~]# echo $myname
	<==这里没有任何数据,因为这个变量没有被设定
[root@study ~]# myname=VBird
[root@study ~]# echo $myname
VBird <==如此一来 myname 这个变量值就被设定成了 VBird 这个变量值

在 bash 中,当一个变量名未被设定值时,预设变量值时空的,在其他某些 shell 中,随便去 echo 一个不存在的变量,可能会出现错误提示信息

变量的设定规则:

  1. 变量与变量值之间使用一个等号【=】来连接

    myname=VBird

  2. 等号两边不能直接接空格符,如下示例为错误:

    myname = VBird 或 myname=VBird Tsai

  3. 变量名只能是英文字母和数字,且开头字符不能是数字,下面示例为错误

    2myname=VBird

  4. 变量值中若有空格符可使用双引号【" "】或单引号【' '】将变量值括起来,但

    • 双引号内的特殊字符如 $ 等,可以保持原有特性,如下所示:

    var="lang is $LANG" 则 echo $var 可以得到 lang is zh_TW.UTF-8

    • 单引号内的特殊字符则仅为一般字符(纯文本),如下所示:

    var='lang is $LANG' 则 echo $var 可得 lang is $LANG

  5. 可以使用转义字符\将特殊符号(如 [enter] ,$,\,空格符,'' 等)转换为一般字符,如:

    myname=VBird\ Tsai

  6. 在一串指令的执行中,如果还需要其他指令计算得到的值作为参数,可以使用返单引号 `指令` 或 $(指令) 这种形式来取用指令执行后的值:

    version=$(uname -r) 再 echo $version 可得 3.10.0-229.el7.x86_64

  7. 若需要为变量扩增内容时,可以用 "$变量名称" 或 ${变量} 追加内容,如下所示:

    PATH="$PATH":/home/bin 或 PATH=${PATH}:/home/bin

  8. 若该变量需要在子程序中使用,则需要使用 export 将变量变成环境变量

    export PATH

  9. 通常大写字符为系统默认变量,自定义变量通常使用小写字符

  10. 取消变量设定的方法为使用 unset:[unset 变量名] 例如取消 myname 的设定:

    unset myname

范例一:设定一变量 name,且内容为 VBird
[root@study ~]# 12name=VBird
bash: 12name=VBird: 未找到命令...
[root@study ~]# name = VBird
bash: name: 未找到命令...
[root@study ~]# name=VBird	<==这才是正确的

范例二:承上例,若变量内容为 VBird's name 呢,就是变量内容含有特殊符号:
[root@study ~]# name=VBird's name
> ^C
#单引号和双引号必须要成对使用,在上面的设定中仅有一个单引号,因此当按下 enter 后,还可以继续输入变量内容
[root@study ~]# name="VBird's name"
[root@study ~]# echo $name
VBird's name
#指令是由左向右执行,先遇到的引号先生效,所以如上所示,单引号变成一般字符了
[root@study ~]# name='VBird's name'
> ^C
#前两个单引号已经成对,后面就多出来一个不成对的单引号
[root@study ~]# name=VBird\'s\ name
#使用转义字符同样有效

范例三:我要在 PATH 这个变量当中追加 :/home/bian/bin 这个目录
[root@study ~]# PATH=$PATH:/home/bian/bin
[root@study ~]# PATH="$PATH":/home/bian/bin
[root@study ~]# PATH=${PATH}:/home/bian/bin
#上面三种格式在给 PATH 变量追加值时,都是 OK 的,但底下的例子就不见得了

范例四:承范例三,我要将 name 的内容追加 "yes"
[root@study ~]# name=$nameyes
[root@study ~]# echo $name

#如果没有使用双引号,则变成了将 nameyes 变量的值赋给 name 变量了,由于 nameyes 变量没有设定过,所以 name 的值也变成空了
[root@study ~]# name="$name"yes
[root@study ~]# echo $name
VBird's nameyes'

范例五:让刚设定的 name=VBird 可以在子程序中使用
[root@study ~]# name=VBird
[root@study ~]# bash	<==进入所谓的子程序
[root@study ~]# echo $name	<==在子程序中 echo name 变量
	<==因为在子程序中没有设定过 name 变量,所以为空
[root@study ~]# exit
exit	<==离开子程序

当你登录 Linux 后取得的 bash 是一个独立的程序,它的识别使用的是 PID,在这个 bash 下启动任何程序(壳程序是其他应用程序接口),都是由这个 bash 衍生出来的子程序,他们也都有自己的 PID,一般情况下,父程序自定义的变量是无法在子程序中使用的,需要使用 export 将变量变成环境变量,就能在子程序下使用了

范例六:如何进入到目前核心的模块目录
[root@study ~]# cd /lib/modules/`uname -r`/kernel
[root@study ~]# cd /lib/modules/$(uname -r)/kernel