14.1 本地变量
本地变量在用户现在的shell 生命期的脚本中使用.这个值只在当前用户生命期有意义,如果在shell启动另一个进程或退出,此值将无效.
使用变量时,如果用花括号将之括起来,可以防止shell 误解变量值.要设置一本地变量,格式为:
$variable-name=value ${variable-name=value}
14.2 显示变量
使用echo 可以显示变量取值,并在变量名前加$,如:
$GRATE="die hard"
$echo ${GRATE}
die hard
$DOLLAR=88
$echo $DOLLAR
88
也可以结合使用变量,下面将错误信息和环境变量LOGNAME设置到变量error_msg
$ERROR_MSG="Sorry this file does not exist user $LOGNAME"
$echo $ERROR_MSG
sorry this file does not exist user root
14.3 清除变量
使用unset 命令清除变量,格式为:
unset variable-name
14.4 显示所有本地shell变量
使用set命令显示所有本地定义的shell变量.
14.5 结合变量值
将变量并排可以使变量结合在一起:
echo $variable_name$variable_name...
例:
$F="Bruce"
$G="Willis"
$echo $F $G
Bruce Willis
14.6 测试变量是否已经设置
有时候需要测试是否已经设置或初始化变量,如果未设置或初始化,就可以使用另一值.命令格式为:
${variable:-value}
意即如果设置了变量值,则使用它,如果未设置则取新值.例:
$COLOR=blue
$echo "The sky is ${COLOR:-grey} today"
The sky is blue today
现在清除该值,再看看结果:
$COLOR=blue
$unset COLOR
$echo "The sky is ${COLOR:-grey} today"
The sky is grey today
上面的例子并没有将实例值传给变量,需使用下列命令完成此功能:
${variable:=value}
可以编写脚本测试变量是否取值,然后返回带有系统错误信息的结果.例:
$echo "The file is ${FILES:?}"
-bash:FILES:parameter null or not set
以上结果可读性不好,但可以自己加入脚本以增加可读性:
$echo "The file is ${FILES:?"sorry cannot locate the variable files"}"
-bash:FILES:sorry cannot locate the variable files
测试变量是否取值,如果未设置,则返回一空串,方法如下:
${variable:+value}
使用下列方法初始化变量未空字符串:
variable=""
$DETINATION=""
14.7 使用变量来保存系统命令参数
可以用变量保存系统命令参数的替换信息.下面的例子使用变量保存文件拷贝的文件名信息.变量source保存passwd文件的路径,dest保存cp命令中文件目标.
$SOURCE="/etc/passwd"
$DEST="/tmp/passwd.bak"
$cp $SOURCE $DEST
14.8 设置只读变量
如果设置变量时,不想改变其值,可设置只读方式,如果有人包括用户本人想改变它,则返回错误信息.
格式:variable-name=value
readonly variable-name
例:
$TEST=ddd
$echo $TEST
ddd
$readonly TEST
$TEST=111
-bash: TEST: readonly variable
要查看所有只读变量,使用命令readonly即可.
$readonly
declare -ar BASH_VERSINFO='([0]="3" [1]="00" [2]="15" [3]="1" [4]="release" [5]="i386-redhat-linux-gnu")'
declare -ir EUID="500"
declare -ir PPID="12614"
declare -r SHELLOPTS="braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor"
declare -r TEST="ddd"
declare -ir UID="500"
14.9 环境变量
环境变量用于所有用户进程(经常称为子进程).登陆进程为父进程.shell中执行的用户进程均称为子进程.
不像本地变量(只用于现在的shell),环境变量可用于所有子进程,这包括编辑器,脚本和应用.
环境变量可以在命令行中设置,但用户注销时这些值将丢失,因此最好在.profile文件中定义.
传统上,所有环境变量均为大写,环境变量应用于用户进程前,必须用export命令导出.环境变量与本地变量设置方式相同.
14.10 设置环境变量
VARIABLE-NAME=value;export VARIABLE-NAME
也可以这样写:
VARIABLE-NAME=value
export VARIABLE-NAME
14.11 显示环境变量
显示环境变量与显示本地变量一样,例:
$CONSOLE=tty1;export CONSOLE
$echo $CONSOLE
tty1
使用env命令可以查看所有的环境变量.
$env
14.12 清除环境变量
$unset $VARIABLE-NAME
14.13 嵌入shell 变量
Brourne shell有一些预留的环境变量名,这些变量名不能作其他用途.通常在/etc/profile中建立这些嵌入的环境变量.以下列举部分变量:
1.CDPATH
改变目录路径变量,保留一系列由冒号隔开的路径名,用于cd命令.如果设置了CDPATH,cd一个目录时,首先查找CDPATH,如果CDPATH指明此目录,则此目录成为当前工作目录.
2.EXINIT
该变量保存使用vi编辑器时的初始化选项,例如,调用vi时,要显示行号,且在第十个空格加入tab键,命令:
$EXINIT='set nu tab=10';export EXINIT
3.HOME
HOME目录通常定位与passwd文件的倒数第二列,用于保存用户自身文件,设置了HOME目录,可以简单使用cd命令进入它.
$cd $HOME
4.IFS
IFS用作shell指定的缺省域分隔符.原理上讲域分隔符可以是任意字符,但缺省通常是空格,新行或tab键盘,IFS在分隔文件或变量中各域时很有用.下面的例子讲IFS设置为冒号,然后echo PATH变量,给出一各目录分隔开来的可读性很强的路径列表.
$echo $PATH
/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/home/smallfish/bin
$export IFS=:
$echo $PATH
/usr/kerberos/bin /usr/local/bin /bin /usr/bin /usr/X11R6/bin /home/smallfish/bin
要设置其返回初始设置:
$IFS=<space><tab>;export IFS
5.LOGNAME
此变量保存登陆名,应该为缺省设置,但如果没有设置,可以使用下面命令完成它:
$LOGNAME='whoami';export LOGNAME
$echo $LOGNAME
smallfish
6.MAIL
MAIL变量保存邮箱路径名,缺省为/var/spool/mail/<login name>.shell周期性检查新邮件,如果有新邮件,在命令行会出现一各提示信息.如果邮箱并不在以上指定位置,可以用MAIL设置.
$MAIL=/usr/mail/smallfish export MAIL
7.MAILCHECK
MAILCHECK 缺省每60s检查新邮件,如果不想如此频繁检查新邮件,比如设为每2m,使用命令:
$MAILCHECK=120 export MAILCHECK
8.MAILPATH
如果有多各邮箱要用到MAILPATH,此变量设置将覆盖MAIL社字汇.
$MAILPATH=/var/spool/smallfish:/var/spool
9.PATH
PATH变量保存进行命令或脚本查找的目录顺序,正确排列这个次序很重要,可以在执行命令时节省时间.通常情况,最好首先放在HOME目录下,接下来是从最常用到一般使用到不常用的目录列表次序.如果要在当前工作目录下查询,无论在哪儿,均可以使用句点操作.目录间用冒号分隔,例如:
$PATH=$HOME/BIN:.:/bin:/usr
PATH可以在系统目录下/etc/profile中设置,也可以使用下面方法加入自己的查找目录.
$PATH=$PATH:/$HOME/bin: export PATH
10.PS1
基本提示符包括shell提示符,缺省对超级用户为#,其他为$.可以使用任何符号作为提示符.
$PS1="star trek:"; export PS1
star trek:
$PS1="->";export PS1
->
11.PS2
PS2为附属提示符,缺省为符号>.PS2用于执行多行命令或超过一行的一各命令.
$PS2="@:"; export PS2
$for loop in *
@:do
@:echo $loop
退出PS2用Ctrl+C
12.SHELL
SHELL变量保存缺省shell,通常在/etc/passwd中已设置,但如果有必要使用另一个shell,可以用如下方法覆盖当前shell:
$echo $SHELL
/bin/bash
13.TERMINFO
终端初始化变量保存终端配置文件的位置.通常在/usr/lib/terminfo或/usr/share/terminfo
$TERMINFO=/usr/lib/terminfo; export TERMINFO
14.TERM
TERM变量保存终端类型.设置TERM使应用获知终端对屏幕和键盘响应的控制序列类型,常用的有vt100,vt200,vt220-8等.
$TERM=vt100;export TERM
15.TZ
时区变量保存时区值,只有系统管理员才可以更改此设置,例:
$echo $TZ
GMT2EDT
返回值表明正在使用格林威治标准时间,与GMT时差威0,并作EDT保存.
14.14 其他环境变量
还有一些
预留的环境变量.其他系统或命令行应用将用到它们.以下是最常用的一些,注意这些值均未有缺省设置,必须显示说明.
1.EDITOR
设置编辑器,最常用.
$EDITOR=vi;export EDITOR
2.PWD
当前路径名,用cd命令设置此选项
3.PAGER
保存屏幕翻页命令,如pg,more,在查看man文本时用到此功能.
$PAGE='pg -f -p';export PAGER
4.MANPATH
保存系统上man文本的目录.目录间用马号分隔.
$MANPATH=/usr/apps/man:/usr/local; export MANPAGE
5.LPDEST或PRINTER
$LPDEST=hp3si-systems
14.15 set 命令
在$HOME.profileW文件中设置环境变量时,还有另一种方法导出这些变量.使用set命令-a选项,即set -a 指明所有变量直接被导出.不要在/etc/profile种使用这种方法,最好只在自己的$HOME.profile文件种使用.
14.16 将变量导出到子进程
shell 新用户碰到的问题之一是定义的变量如何导出到子进程.前面已经讨论过环境变量的工作方式,现在用脚本实现它,并在脚本种调用另一脚本
(这实际上创建了一个子进程).
以下是两个脚本列表father和child.
father脚本设置变量film,取值为 A Few Good Men,并将变量信息返回屏幕,然后调用脚本child,这段脚本显示第一个脚本里的变量film,然后改变其值为Die Hard,再将其显示在屏幕上,最后控制反活father脚本,再次显示这个变量.
$more father
#!/bin/bash
#father script.
echo "this is the father"
FILM="A Few Good Men"
echo "I like the film:$FILM"
#call the child script
./child
echo "back to father"
echo "and the film is:$FILM"
more child
#!/bin/sh
#child
echo "called from father..i am the child"
echo "film name is :$FILM"
FILM="Die Hard"
echo "changing film to :$FILM"
脚本显示结果:
$./father
this is the father
I like the film:A Few Good Men
called from father.. i am the child
film name is :
changing film to :die Hard
back to father
and the film is:A Few Good Men
$./child
called from father.. i am the child
film name is :
changing film to :die Hard
因为在father种并未导出变量film,因此child脚本不能将film变量返回.
如果在father脚本种加入export命令,以便child脚本知道film变量的取值,这就会工作:
$vi father
#!/bin/bash
#father script
echo "this is the father"
FILM="A Few Good Men"
echo "I like the film ;$FILM"
#call the child script
#but export variable first
export FILM
./child
echo "back to father"
echo "and the film is :$FILM"
$./father
this is the father
I like the film:A Few Good Men
called from father.. i am the child
film name is :A Few Good Men
changing film to :die Hard
back to father
and the film is:A Few Good Men
因为在脚本中加入了export命令,因此可以在任意多的脚本中使用变量film,它们均继承了film的所有权.
不可以将变量从子进程导出到文件进程,然而通过重定向就可以做到这一点.
14.17 位置变量参数
本章开始提到有4种变量,本地,环境.还有两种变量被认为是特殊变量,因为他们是只读的.这两种变量即为位置变量和特定变量参数,先来看位置变量.
如果要向一个shell脚本传递信息,可以使用位置参数完成此功能.
1.在脚本中使用位置参数
2.向系统命令传递参数
14.18 特定变量参数
既然已经知道了如何访问和使用shell脚本中的参数,多知道一点相关信息也是有用的,有必要知道脚本运行时的一些相关控制信息,这就是特定变量的由来.共有7个特定变量:
$# 传递到脚本的参数个数
$* 以一个单字符串显示所有向脚本传递的参数.与位置变量不同,此选项参数可超过9个
$$ 脚本运行的当前进程ID号
$! 后台运行的最后一个进程的进程ID号
$@ 与$#相同,但是使用时加引号,并在引号中返回每个参数
$- 显示shell使用的当前选项,与set命令功能相同
$? 显示最后命令的退出状态.0表示没有错误,其他任何值表明有错误.
14.19 最后的退出状态
注意,$?返回0,可以在任何命令或脚本中返回此变量以获得返回信息.基于此信息,可以在脚本中做更进一步的研究,返回0意味着成功,1为出现错误.
下面的例子是拷贝文件到/tmp,并使用$?检查结果:
$cp ok.txt /tmp
$echo $?
0