变量允许临时将信息存储在shell脚本中,以便和脚本中的其它命令一起使用。在Linux系统中,可总结为两种变量类型,一种是环境变量,一种是用户变量。
1. 环境变量
bash shell用一个叫作环境变量的特性来存储有关shell会话和工作环境的信息(这也是它们被称作环境变量的原因)。这项特性允许你在内存中存储数据,以便程序或shell中运行的脚本能够轻松访问到它们。这也是存储持久数据的一种简便方法。一般系统环境变量是大写。
在bash shell中,环境变量还可以分成两类:全局变量、局部变量
(1)全局变量
全局环境变量对与shell会话以及它所有的子shell都是可见的。因此,这对子shell想要访问父shell的信息是非常重要的。比如:
[Hermioner@localhost Documents]$ ps -f //显示当前进程信息
UID PID PPID C STIME TTY TIME CMD
Hermion+ 3678 3673 0 18:56 pts/0 00:00:00 bash
Hermion+ 4245 3678 0 19:21 pts/0 00:00:00 ps -f
[Hermioner@localhost Documents]$ bash
[Hermioner@localhost Documents]$ bash
[Hermioner@localhost Documents]$ ps -f #多了两个子shell
UID PID PPID C STIME TTY TIME CMD
Hermion+ 3678 3673 0 18:56 pts/0 00:00:00 bash
Hermion+ 4249 3678 0 19:21 pts/0 00:00:00 bash
Hermion+ 4283 4249 0 19:21 pts/0 00:00:00 bash
Hermion+ 4317 4283 0 19:21 pts/0 00:00:00 ps -f
[Hermioner@localhost Documents]$ printenv HOME #在最后一个子shell中输出系统全局环境变量的值
/home/Hermioner
[Hermioner@localhost Documents]$
note:要查看全局变量,可以用env或者printenv。但是如果要查看具体的环境变量的值,只可以用printenv 环境变量名 来实现。eg: printenv HOME 。当
然 ,也可以直接通过echo语句输出具体值,eg: echo $HOME
(2)局部环境变量
局部环境变量只能在创建该变量的shell中使用,它的父shell和子shell都不能访问它。
note:在Linux系统中并没有一个只显示局部环境变量的命令。set命令会显示为某个特定进程设置的所有环境变量,包括局部变量、全局变量以及用户定义变 量。
2. 用户定义变量
一般用户定义变量是小写。仍然分为全局和局部用户定义变量。设置自定义变量时直接采用 变量名=值(可以是数值或字符串,如果写的浮点,就当成字符串处理了,也或者在数值运算时报错)。注意,变量名、等号和值之间没有空格,否则bash shell将会把值当作一个单独的命令来执行,导致报错。
(1)全局用户定义变量
全局用户定义变量的进程所创建的子进程中,这个变量是可见的。但创建全局变量需要先创建一个局部变量,再用export将变量导出成为全局变量。
eg: a=1
export a
bash
echo $a 最终值为1,子shell访问到了这个全局用户定义变量
note:修改子shell中的全局变量,并试图export成全局变量,并不会更改之前定义的这个同名全局变量。比如在子shell中将a改为3,并export。回到父shell 后,a的值仍然是1.
(2)局部用户定义变量
作用域同局部环境变量。
3. 删除环境变量
删除环境变量就是对变量的操作。在linux中记住,如果要用到变量,就用$;如果要操作变量,不使用$。而删除的命令即 unset 变量名。
eg:unset my_variable
note:和修改变量一样,在子shell中删除全局变量以后,你无法将效果反映到父shell中。
4. PATH环境变量
无论是输入命令还是执行shell脚本,shell必须搜索系统来找到对应的程序。那究竟根据什么来查找定位呢?PATH环境变量定义了用于进行命令和程序查找的目录。先打印输出Linux中已经定义好的路径,总共有8个,用冒号隔开:
[Hermioner@localhost ~]$ echo $PATH
/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/home/Hermioner/.local/bin:/home/Hermioner/bin
比如我们查看ls命令所在路径:
[Hermioner@localhost ~]$ which ls #也可以用whereis ls 哈
alias ls='ls --color=auto'
/usr/bin/ls #这就是路径,查看PATH给出的路径中,第三个匹配,这样就能够在任何地方输出ls命令后,就能够得到想要的结果啦,因为有PATH这个系统环境变量来帮忙定位。
但是,如果我们写的一些脚本什么的并没有在上面默认的8个路径下,且又不想要使用绝对路径来执行脚本,那么有两种解决办法
(1)非永久生效办法--------修改PATH变量的值
采用 PATH=$PATH:需要被识别的路径 这样的格式就可以改变PATH的值了。这样就可以不用输入绝对路径的条件下使用bash命令来执行脚本了。
eg: PATH=$PATH:/home/a (假设目录a下面有个脚本b.sh)就不用到目录a下面来执行脚本b.sh,home下可以直接执行b.sh
note:这种办法只要一旦关闭命令窗口就会失效。
(2)永久有效办法
在系统启动文件/etc/profile中定义用户需要的变量。这个文件中有很多的循环语句,通过这些语句的判断执行来定位路径。(暂时不管这个)
bash shell会在启动时执行几个启动文件。这些启动文件包含了环境变量的定义,可用于为每个bash会话设置标准环境变量。每次登陆Linux系统,bash shell都会访问/etc/profile启动文件以及3个针对每个用户的本地启动文件:$HOME/.bash_profile、$HOME/.bash_login和$HOME/.profile。用户可以在这些 文件中定制自己想要的环境变量和启动脚本。
5. 数组变量
要给某个变量设置多个值,可以把值放在括号里,并且只可以通过索引来引用(索引从0开始)。如下格式:
[Hermioner@localhost ~]$ a=(one two three four five)
[Hermioner@localhost ~]$ echo $a #没加索引,默认输出第一个值
one
[Hermioner@localhost ~]$ echo ${a[3]}
four
[Hermioner@localhost ~]$ unset a[3] #删除了索引为3的值
[Hermioner@localhost ~]$ echo ${a[3]} #结果是null
[Hermioner@localhost ~]$ echo ${a[4]}
five
[Hermioner@localhost ~]$ echo ${a[*]} #使用通配符,输出所有值
one two three five
note:有时数组变量会让事很麻烦,所以在shell脚本编程时并不常用。并且,对于其它shell而言,数组变量的可移植性并不好,不方便。
6. 变量的使用
可以通过在变量名字前面添加美元符号($)来使用这些变量。但是如果想要使用美元符号本身,就需要转义,添加反斜杠就可以。比如:
[Hermioner@localhost Documents]$ a=hello
[Hermioner@localhost Documents]$ echo $a
hello
[Hermioner@localhost Documents]$ a=$3
[Hermioner@localhost Documents]$ echo $a
[Hermioner@localhost Documents]$ a=$3
[Hermioner@localhost Documents]$ echo $a
$3
note1:你也可以用${varable}形式来引用变量。
用户变量可以是任何由字母、数字或下划线组成的文本字符串,长度不超过20个。在变量、等号和值之间不能出现空格。
note2:不加$是赋的变量本身,相当于引用。加上$才是值
note3:命令输出结果赋给变量:(记住,是命令)
testing=`date` 或者testing=$(date) 必须加括号
总结一句话,引用变量的值,用$变量名 ; 引用命令结果的值,用$(命令) ; 引用算数表达式结果,用 $[算数表达式]
参考文献:
Linux命令行与shell脚本编程大全(第3版)[美] 布鲁姆(Richard Blum),布雷斯纳汉(Christine Bresnahan) 著,门佳,武海峰 译