什么是变量?
那么,什么是『变量』呢?简单的说,就是让某一个特定字符串代表不固定的内容就是了。举个大家在国中都会学到的数学例子,
那就是:『 y = ax + b 』这东西,在等号左边的(y)就是变量,在等号右边的(ax+b)就是变量内容。
要注意的是,左边是未知数,右边是已知数喔!
讲的更简单一点,我们可以『用一个简单的 "字眼"
来取代另一个比较复杂或者是容易变动的数据』。这有什么好处啊?最大的好处就是『方便!』。
最后我们就简单的对『什么是变量』作个简单定义好了: 『变量就是以一组文字或符号等,来取代一些配置或者是一串保留的数据!』, 例如:我配置了『myname』就是『VBird』,所以当你读取 myname 这个变量的时候,系统自然就会知道!哈!那就是 VBird 啦! 那么如何『显示变量』呢?这就需要使用到 echo 这个命令啦!
影响 bash 环境操作的变量
某些特定变量会影响到 bash 的环境喔!举例来说,我们前面已经提到过很多次的那个 PATH 变量! 你能不能在任何目录下运行某个命令,与 PATH 这个变量有很大的关系。例如你下达 ls 这个命令时,系统就是透过 PATH 这个变量里面的内容所记录的路径顺序来搜寻命令的呢!如果在搜寻完 PATH 变量内的路径还找不到 ls 这个命令时, 就会在屏幕上显示『 command not found 』的错误信息了。
变量的取用与配置:echo, 变量配置守则, unset
- 变量的取用: echo
[root@www ~]# echo $variable |
变量的取用就如同上面的范例,利用 echo 就能够读出,只是需要在变量名称前面加上 $ , 或者是以 ${变量} 的方式来取用都可以!当然啦,那个 echo 的功能可是很多的, 我们这里单纯是拿 echo 来读出变量的内容而已,更多的 echo 使用,请自行给他 man echo 吧! ^_^
例题:
请在屏幕上面显示出您的环境变量 HOME 与 MAIL:
答: echo $HOME 或者是 echo ${HOME}
echo $MAIL 或者是 echo ${MAIL} |
现在我们知道了变量与变量内容之间的相关性了,好了,那么我要如何『配置』或者是『修改』
某个变量的内容啊?很简单啦!用『等号(=)』连接变量与他的内容就好啦!举例来说:
我要将 myname 这个变量名称的内容配置为 VBird ,那么:
[root@www ~]# echo $myname |
瞧!如此一来,这个变量名称 myname 的内容就带有 VBird 这个数据啰~ 而由上面的例子当中,我们也可以知道: 在 bash 当中,当一个变量名称尚未被配置时,默认的内容是『空』的。 另外,变量在配置时,还是需要符合某些规定的,否则会配置失败喔! 这些守则如下所示啊!
- 变量的配置守则
- 变量与变量内容以一个等号『=』来连结,如下所示:
『myname=VBird』 - 等号两边不能直接接空格符,如下所示为错误:
『myname = VBird』或『myname=VBird Tsai』 - 变量名称只能是英文字母与数字,但是开头字符不能是数字,如下为错误:
『2myname=VBird』 - 变量内容若有空格符可使用双引号『"』或单引号『'』将变量内容结合起来,但
- 双引号内的特殊字符如 $ 等,可以保有原本的特性,如下所示:
『var="lang is $LANG"』则『echo $var』可得『lang is en_US』 - 单引号内的特殊字符则仅为一般字符 (纯文本),如下所示:
『var='lang is $LANG'』则『echo $var』可得『lang is $LANG』
- 双引号内的特殊字符如 $ 等,可以保有原本的特性,如下所示:
- 可用跳脱字符『 \ 』将特殊符号(如 [Enter], $, \, 空格符,
'等)变成一般字符; - 在一串命令中,还需要藉由其他的命令提供的信息,可以使用反单引号『`命令`』或
『$(命令)』。特别注意,那个 ` 是键盘上方的数字键 1 左边那个按键,而不是单引号!
例如想要取得核心版本的配置:
『version=$(uname -r)』再『echo
$version』可得『2.6.18-128.el5』 - 若该变量为扩增变量内容时,则可用 "$变量名称" 或 ${变量} 累加内容,如下所示:
『PATH="$PATH":/home/bin』 - 若该变量需要在其他子程序运行,则需要以 export 来使变量变成环境变量:
『export PATH』 - 通常大写字符为系统默认变量,自行配置变量可以使用小写字符,方便判断 (纯粹依照使用者兴趣与嗜好) ;
- 取消变量的方法为使用 unset :『unset
变量名称』例如取消 myname 的配置:
『unset myname』 - 什么是『子程序』呢?就是说,在我目前这个 shell 的情况下,去激活另一个新的 shell ,新的那个 shell 就是子程序啦!在一般的状态下,父程序的自定义变量是无法在子程序内使用的。但是透过 export 将变量变成环境变量后,就能够在子程序底下应用了!
环境变量的功能
环境变量=全局变量
自定义变量=局部变量
- 用 env 观察环境变量与常见环境变量说明(环境变量)
- 用 set 观察所有变量 (含环境变量与自定义变量)
-
[root@iZ288fgkcpkZ lianxi]# set
BASH=/bin/bash
............................(略)
SSH_TTY=/dev/pts/
TERM=xterm
UID=
nange=zhaoyingnan主要是看这,我自己设置的也会显示
[root@iZ288fgkcpkZ lianxi]#PS1:(提示字符的配置)
这是 PS1 (数字的 1 不是英文字母),这个东西就是我们的『命令提示字符』喔!
当我们每次按下 [Enter] 按键去运行某个命令后,最后要再次出现提示字符时,
就会主动去读取这个变量值了。上头 PS1 内显示的是一些特殊符号,这些特殊符号可以显示不同的信息,
每个 distributions 的 bash 默认的 PS1 变量内容可能有些许的差异,不要紧,『习惯你自己的习惯』就好了。
你可以用 man bash (注3)去查询一下 PS1 的相关说明,以理解底下的一些符号意义。- \d :可显示出『星期 月 日』的日期格式,如:"Mon Feb 2"
- \H :完整的主机名。举例来说,鸟哥的练习机为『www.vbird.tsai』
- \h :仅取主机名在第一个小数点之前的名字,如鸟哥主机则为『www』后面省略
- \t :显示时间,为 24 小时格式的『HH:MM:SS』
- \T :显示时间,为 12 小时格式的『HH:MM:SS』
- \A :显示时间,为 24 小时格式的『HH:MM』
- \@ :显示时间,为 12 小时格式的『am/pm』样式
- \u :目前使用者的账号名称,如『root』;
- \v :BASH 的版本信息,如鸟哥的测试主板本为 3.2.25(1),仅取『3.2』显示
- \w :完整的工作目录名称,由根目录写起的目录名称。但家目录会以 ~ 取代;
- \W :利用 basename 函数取得工作目录名称,所以仅会列出最后一个目录名。
- \# :下达的第几个命令。
- \$ :提示字符,如果是 root 时,提示字符为 # ,否则就是 $ 啰~
-
3. export: 自定义变量转成环境变量
谈了 env 与 set 现在知道有所谓的环境变量与自定义变量,那么这两者之间有啥差异呢?其实这两者的差异在于『 该变量是否会被子程序所继续引用』啦!
[root@iZ288fgkcpkZ lianxi]# echo $nange
zhaoyingnan
[root@iZ288fgkcpkZ lianxi]# bash
[root@iZ288fgkcpkZ lianxi]# echo $nange
#在子程序里是空的哦
[root@iZ288fgkcpkZ lianxi]# exit
exit
[root@iZ288fgkcpkZ lianxi]# export nange这样就可以了
[root@iZ288fgkcpkZ lianxi]# bash
[root@iZ288fgkcpkZ lianxi]# echo $nange
zhaoyingnan
[root@iZ288fgkcpkZ lianxi]# exit
[root@iZ288fgkcpkZ lianxi]#
4. 在学理方面,为什么环境变量的数据可以被子程序所引用呢?这是因为内存配置的关系!理论上是这样的:
- 当启动一个 shell,操作系统会分配一记忆区块给 shell 使用,此内存内之变量可让子程序取用
- 若在父程序利用 export 功能,可以让自定义变量的内容写到上述的记忆区块当中(环境变量);
- 当加载另一个 shell 时 (亦即启动子程序,而离开原本的父程序了),子 shell 可以将父 shell 的环境变量所在的记忆区块导入自己的环境变量区块当中。
变量键盘读取、数组与宣告: read, array, declare
- read
要读取来自键盘输入的变量,就是用 read 这个命令了。
[root@www ~]# read [-pt] variable
选项与参数:
-p :后面可以接提示字符!
-t :后面可以接等待的『秒数!』这个比较有趣~不会一直等待使用者啦! 范例一:让用户由键盘输入一内容,将该内容变成名为 atest 的变量
[root@www ~]# read atest
This is a test <==此时光标会等待你输入!请输入左侧文字看看
[root@www ~]# echo $atest
This is a test <==你刚刚输入的数据已经变成一个变量内容! 范例二:提示使用者 30 秒内输入自己的大名,将该输入字符串作为名为 named 的变量内容
[root@www ~]# read -p "Please keyin your name: " -t 30 named
Please keyin your name: VBird Tsai <==注意看,会有提示字符喔!
[root@www ~]# echo $named
VBird Tsai <==输入的数据又变成一个变量的内容了!
- declare / typeset
declare 或 typeset 是一样的功能,就是在『宣告变量的类型』。如果使用 declare 后面并没有接任何参数,那么 bash 就会主动的将所有的变量名称与内容通通叫出来,就好像使用 set 一样啦!
[root@www ~]# declare [-aixr] variable
选项与参数:
-a :将后面名为 variable 的变量定义成为数组 (array) 类型
-i :将后面名为 variable 的变量定义成为整数数字 (integer) 类型
-x :用法与 export 一样,就是将后面的 variable 变成环境变量;
-r :将变量配置成为 readonly 类型,该变量不可被更改内容,也不能 unset 范例一:让变量 sum 进行 100+300+50 的加总结果
[root@www ~]# sum=100+300+50
[root@www ~]# echo $sum
100+300+50 <==咦!怎么没有帮我计算加总?因为这是文字型态的变量属性啊!
[root@www ~]# declare -i sum=100+300+50
[root@www ~]# echo $sum
450 <==瞭乎??
由于在默认的情况底下, bash 对于变量有几个基本的定义:
- 变量类型默认为『字符串』,所以若不指定变量类型,则 1+2 为一个『字符串』而不是『计算式』。 所以上述第一个运行的结果才会出现那个情况的;
-
bash 环境中的数值运算,默认最多仅能到达整数形态,所以 1/3 结果是 0
范例二:将 sum 变成环境变量
[root@www ~]# declare -x sum
[root@www ~]# export | grep sum
declare -ix sum="450" <==果然出现了!包括有 i 与 x 的宣告! 范例三:让 sum 变成只读属性,不可更动!
[root@www ~]# declare -r sum
[root@www ~]# sum=tesgting
-bash: sum: readonly variable <==老天爷~不能改这个变量了! 范例四:让 sum 变成非环境变量的自定义变量吧!
[root@www ~]# declare +x sum <== 将 - 变成 + 可以进行『取消』动作
[root@www ~]# declare -p sum <== -p 可以单独列出变量的类型
declare -ir sum="450" <== 看吧!只剩下 i, r 的类型,不具有 x 啰!
- 变量的测试与内容替换
在某些时刻我们常常需要『判断』某个变量是否存在,若变量存在则使用既有的配置,若变量不存在则给予一个常用的配置。
[root@iZ288fgkcpkZ lianxi]# echo $nange
zhaoyingnan
[root@iZ288fgkcpkZ lianxi]# unset nange;sName=${nange=wuchang}
[root@iZ288fgkcpkZ lianxi]# echo $nange
wuchang
[root@iZ288fgkcpkZ lianxi]# echo $wuchang [root@iZ288fgkcpkZ lianxi]# echo $sName
wuchang
[root@iZ288fgkcpkZ lianxi]#
变量配置方式 | str 没有配置 | str 为空字符串 | str 已配置非为空字符串 |
var=${str-expr} | var=expr | var= | var=$str |
var=${str:-expr} | var=expr | var=expr | var=$str |
var=${str+expr} | var= | var=expr | var=expr |
var=${str:+expr} | var= | var= | var=expr |
var=${str=expr} | str=expr var=expr |
str 不变 var= |
str 不变 var=$str |
var=${str:=expr} | str=expr var=expr |
str=expr var=expr |
str 不变 var=$str |
var=${str?expr} | expr 输出至 stderr | var= | var=$str |
var=${str:?expr} | expr 输出至 stderr | expr 输出至 stderr | var=$str |