分类: Python/Ruby
2011-08-10 10:46:44
这些内建的变量,将影响bash脚本的行为.
$BASH
这个变量将指向Bash的二进制执行文件的位置.
bash$ echo $BASH
/bin/bash
$BASH_ENV
这个环境变量将指向一个Bash启动文件,这个启动文件将在调用一个脚本时被读取.
$BASH_SUBSHELL
这个变量将提醒subshell的层次,这是一个在version3才被添加到Bash中的新特性.
见Example 20-1.
$BASH_VERSINFO[n]
记录Bash安装信息的一个6元素的数组.与下边的$BASH_VERSION很像,但这个更加详细.
1 # Bash version info:
2
3 for n in 0 1 2 3 4 5
4 do
5 echo "BASH_VERSINFO[$n] = ${BASH_VERSINFO[$n]}"
6 done
7
8 # BASH_VERSINFO[0] = 3 # 主版本号
9 # BASH_VERSINFO[1] = 00 # 次版本号
10 # BASH_VERSINFO[2] = 14 # Patch 次数.
11 # BASH_VERSINFO[3] = 1 # Build version.
12 # BASH_VERSINFO[4] = release # Release status.
13 # BASH_VERSINFO[5] = i386-redhat-linux-gnu # Architecture
$BASH_VERSION
安装在系统上的Bash的版本号.
bash$ echo $BASH_VERSION
3.00.14(1)-release
tcsh% echo $BASH_VERSION
BASH_VERSION: Undefined variable.
使用这个变量对于判断系统上到底运行的是那个shll来说是一种非常好的办法.$SHELL
有时将不能给出正确的答案.
$DIRSTACK
在目录栈中最上边的值(将受到pushd和popd的影响).
这个内建的变量与dirs命令是保持一致的,但是dirs命令将显示目录栈的整个内容.
$EDITOR
脚本调用的默认编辑器,一般是vi或者是emacs.
$EUID
"effective"用户ID号.
当前用户被假定的任何id号.可能在su命令中使用.
注意:$EUID并不一定与$UID相同.
$FUNCNAME
当前函数的名字.
1 xyz23 ()
2 {
3 echo "$FUNCNAME now executing." # xyz23 现在正在被执行.
4 }
5
6 xyz23
7
8 echo "FUNCNAME = $FUNCNAME" # FUNCNAME =
9 # 出了函数就变为Null值了.
$GLOBIGNORE
一个文件名的模式匹配列表,如果在file globbing中匹配到的文件包含这个列表中的
某个文件,那么这个文件将被从匹配到的文件中去掉.
$GROUPS
当前用户属于的组.
这是一个当前用户的组id列表(数组),就像在/etc/passwd中记录的一样.
root# echo $GROUPS
0
root# echo ${GROUPS[1]}
1
root# echo ${GROUPS[5]}
6
$HOME
用户的home目录,一般都是/home/username(见Example 9-14)
$HOSTNAME
hostname命令将在一个init脚本中,在启动的时候分配一个系统名字.
gethostname()函数将用来设置这个$HOSTNAME内部变量.(见Example 9-14)
$HOSTTYPE
主机类型
就像$MACHTYPE,识别系统的硬件.
bash$ echo $HOSTTYPE
i686
$IFS
内部域分隔符.
这个变量用来决定Bash在解释字符串时如何识别域,或者单词边界.
$IFS默认为空白(空格,tab,和新行),但可以修改,比如在分析逗号分隔的数据文件时.
注意:$*使用$IFS中的第一个字符,具体见Example 5-1.
bash$ echo $IFS | cat -vte
$
bash$ bash -c 'set w x y z; IFS=":-;"; echo "$*"'
w:x:y:o
注意:$IFS并不像它处理其它字符一样处理空白.
$IGNOREEOF
忽略EOF: 告诉shell在log out之前要忽略多少文件结束符(control-D).
$LC_COLLATE
常在.bashrc或/etc/profile中设置,这个变量用来在文件名扩展和模式匹配校对顺序.
如果$LC_COLLATE被错误的设置,那么将会在filename globbing中引起错误的结果.
注意:在2.05以后的Bash版本中,filename globbing将不在对[]中的字符区分大小写.
比如:ls [A-M]* 将即匹配File1.txt也会匹配file1.txt.为了恢复[]的习惯用法,
设置$LC_COLLATE的值为c,使用export LC_COLLATE=c 在/etc/profile或者是
~/.bashrc中.
$LC_CTYPE
这个内部变量用来控制globbing和模式匹配的字符串解释.
$LINENO
这个变量记录它所在的shell脚本中它所在行的行号.这个变量一般用于调试目的.
1 # *** BEGIN DEBUG BLOCK ***
2 last_cmd_arg=$_ # Save it.
3
4 echo "At line number $LINENO, variable \"v1\" = $v1"
5 echo "Last command argument processed = $last_cmd_arg"
6 # *** END DEBUG BLOCK ***
$MACHTYPE
系统类型
提示系统硬件
bash$ echo $MACHTYPE
i686
$OLDPWD
老的工作目录("OLD-print-working-directory",你所在的之前的目录)
$OSTYPE
操作系统类型.
bash$ echo $OSTYPE
linux
$PATH
指向Bash外部命令所在的位置,一般为/usr/bin,/usr/X11R6/bin,/usr/local/bin等.
当给出一个命令时,Bash将自动对$PATH中的目录做一张hash表.$PATH中以":"分隔的
目录列表将被存储在环境变量中.一般的,系统存储的$PATH定义在/ect/processed或
~/.bashrc中(见Appendix G).
bash$ echo $PATH
/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin:/sbin:/usr/sbin
PATH=${PATH}:/opt/bin将把/opt/bin目录附加到$PATH变量中.在脚本中,这是一个
添加目录到$PATH中的便捷方法.这样在这个脚本退出的时候,$PATH将会恢复(因为这个
shell是个子进程,像这样的一个脚本是不会将它的父进程的环境变量修改的)
注意:当前的工作目录"./"一般都在$PATH中被省去.
$PIPESTATUS
数组变量将保存最后一个运行的前台管道的退出码.有趣的是,这个退出码和最后一个命令
运行的退出码并不一定相同.
bash$ echo $PIPESTATUS
0
bash$ ls -al | bogus_command
bash: bogus_command: command not found
bash$ echo $PIPESTATUS
141
bash$ ls -al | bogus_command
bash: bogus_command: command not found
bash$ echo $?
127
$PIPESTATUS数组的每个成员都会保存一个管道命令的退出码,$PIPESTATUS[0]保存第
一个管道命令的退出码,$PIPESTATUS[1]保存第2个,以此类推.
注意:$PIPESTATUS变量在一个login shell中可能会包含一个错误的0值(3.0以下版本)
tcsh% bash
bash$ who | grep nobody | sort
bash$ echo ${PIPESTATUS[*]}
0
包含在脚本中的上边这行将会产生一个期望的输出0 1 0.
注意:在某些上下文$PIPESTATUS可能不会给出正确的结果.
bash$ echo $BASH_VERSION
3.00.14(1)-release
bash$ $ ls | bogus_command | wc
bash: bogus_command: command not found
0 0 0
bash$ echo ${PIPESTATUS[@]}
141 127 0
Chet Ramey把上边输出不成确原因归咎于ls的行为.因为如果把ls的结果放到管道上,
并且这个输出没被读取,那么SIGPIPE将会kill掉它,并且退出码变为141,而不是我们期
望的0.这种情况也会发生在tr命令中.
注意:$PIPESTATUS是一个"volatile"变量.在任何命令插入之前,并且在pipe询问之后,
这个变量需要立即被捕捉.
bash$ $ ls | bogus_command | wc
bash: bogus_command: command not found
0 0 0
bash$ echo ${PIPESTATUS[@]}
0 127 0
bash$ echo ${PIPESTATUS[@]}
0
$PPID
一个进程的$PPID就是它的父进程的进程id(pid).[1]
使用pidof命令对比一下.
$PROMPT_COMMAND
这个变量保存一个在主提示符($PS1)显示之前需要执行的命令.
$PS1
主提示符,具体见命令行上的显示.
$PS2
第2提示符,当你需要额外的输入的时候将会显示,默认为">".
$PS3
第3提示符,在一个select循环中显示(见Example 10-29).
$PS4
第4提示符,当使用-x选项调用脚本时,这个提示符将出现在每行的输出前边.
默认为"+".
$PWD
工作目录(你当前所在的目录).
与pwd内建命令作用相同.
$REPLY
read命令如果没有给变量,那么输入将保存在$REPLY中.在select菜单中也可用,但是只
提供选择的变量的项数,而不是变量本身的值.
# REPLY是'read'命令结果保存的默认变量.
$SECONDS
这个脚本已经运行的时间(单位为秒).
1 #!/bin/bash
2
3 TIME_LIMIT=10
4 INTERVAL=1
5
6 echo
7 echo "Hit Control-C to exit before $TIME_LIMIT seconds."
8 echo
9
10 while [ "$SECONDS" -le "$TIME_LIMIT" ]
11 do
12 if [ "$SECONDS" -eq 1 ]
13 then
14 units=second
15 else
16 units=seconds
17 fi
18
19 echo "This script has been running $SECONDS $units."
20 # 在一台比较慢的或者是负载很大的机器上,这个脚本可能会跳过几次循环
21 #+ 在一个while循环中.
22 sleep $INTERVAL
23 done
24
25 echo -e "\a" # Beep!
26
27 exit 0
$SHELLOPTS
这个变量里保存shell允许的选项,这个变量是只读的.
bash$ echo $SHELLOPTS
braceexpand:hashall:histexpand:monitor:history:interactive-comments:emacs
$SHLVL
Shell层次,就是shell层叠的层次,如果是命令行那$SHLVL就是1,如果命令行执行的脚
本中,$SHLVL就是2,以此类推.
$TMOUT
如果$TMOUT环境变量被设置为一个非零的时间值,那么在过了这个指定的时间之后,
shell提示符将会超时,这会引起一个logout.
在2.05b版本的Bash中,已经支持在一个带有read命令的脚本中使用$TMOUT变量.
1 # 需要使用Bash v2.05b或者以后的版本上
2
3 TMOUT=3 # Prompt times out at three seconds.
3 TMOUT=3 # 设置超时的时间为3秒
4
5 echo "What is your favorite song?"
6 echo "Quickly now, you only have $TMOUT seconds to answer!"
7 read song
8
9 if [ -z "$song" ]
10 then
11 song="(no answer)"
12 # 默认响应.
13 fi
14
15 echo "Your favorite song is $song."
这里有一个更复杂的方法来在一个脚本中实现超时功能.一种办法就是建立一个时间循
环,在超时的时候通知脚本.不过,这也需要一个信号处理机制,在超时的时候来产生中
断.
位置参数:
详见ABS(Advanced Bash Shell)中文翻译版103页第9章第一节内部变量,当然英文版ABS都一样啦
$1, $2, $3等等...
位置参数,从命令行传递给脚本,或者是传递给函数.或者赋职给一个变量.
此数目可以任意多,但只有前9个可以被访问,使用shift命令可以改变这个限制。
(具体见Example 4-5 和Example 11-15)
$0
$0表示当前执行的进程名,script 本身的名字,或者在正则表达式中表示整行输出
$#
命令行或者是位置参数的个数.(见Example 33-2)
$*
所有的位置参数,被作为一个单词.
注意:"$*"必须被""引用.
$@
与$*同义,但是每个参数都是一个独立的""引用字串,这就意味着参数被完整地传递,
并没有被解释和扩展.这也意味着,每个参数列表中的每个参数都被当成一个独立的单词.
注意:"$@"必须被""引用.
其他的特殊参数
$-
传递给脚本的falg(使用set 命令).参考Example 11-15.
显示shell使用的当前选项,与set命令功能相同
注意:这起初是ksh 的特征,后来被引进到Bash 中,但不幸的是,在Bash 中它看上去也不
能可靠的工作.使用它的一个可能的方法就是让这个脚本进行自我测试(查看是否是交
互的).
$!
在后台运行的最后的工作的PID(进程ID).
$_
保存之前执行的命令的最后一个参数.
$?
命令,函数或者脚本本身的退出状态(见Example 23-7)
用于检查上一个命令,函数或者脚本执行是否正确。(在Linux中,命令退出状态为0表示该命令正确执行,任何非0值表示命令出错。)
$$
脚本自身的进程ID.这个变量经常用来构造一个"unique"的临时文件名.
(参考Example A-13,Example 29-6,Example 12-28 和Example 11-25).
这通常比调用mktemp 来得简单.
注意事项:
[1] 当前运行的脚本的PID 为$$.
[2] "argument"和"parameter"这两个单词经常不加区分的使用.在这整本书中,这两个
单词的意思完全相同.(在翻译的时候就未加区分,统统翻译成参数)