分类:
2010-01-03 22:29:19
摘自《高级bash脚本编程指南》
$BASH
Bash的二进制程序文件的路径
bash$ echo $BASH /bin/bash
$BASH_ENV
这个环境变量会指向一个Bash的启动文件, 当一个脚本被调用的时候, 这个启动文件将会被读取.
$BASH_SUBSHELL
这个变量用来提示子shell的层次. 这是一个Bash的新特性, 直到版本3的Bash才被引入近来.
$BASH_VERSINFO[n]
这是一个含有 6 个元素的数组, 它包含了所安装的Bash的版本信息. 这与下边的$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] = 2 # 次版本号. 10 # BASH_VERSINFO[2] = 39 # 补丁次数. 11 # BASH_VERSINFO[3] = 1 # 编译版本. 12 # BASH_VERSINFO[4] = release # 发行状态. 13 # BASH_VERSINFO[5] = i486-pc-linux-gnu # 结构体系 14 # (与变量$MACHTYPE相同).
$BASH_VERSION
安装在系统上的Bash版本号
fhc2007@fhc2007-desktop:~/program$ echo $BASH_VERSION 3.2.39(1)-release
$EUID
“有效”用户ID
不管当前用户被假定成什么用户, 这个数都用来表示当前用户的标识号, 也可能使用su命令来达到假定的目的.
注: $EUID并不一定与$UID相同.
$FUNCNAME
当前函数的名字
1 xyz23 () 2 { 3 echo "$FUNCNAME now executing." # 打印: xyz23 now executing. 4 } 5 6 xyz23 7 8 echo "FUNCNAME = $FUNCNAME" # FUNCNAME = 9 # 超出函数的作用域就变为null值了.
$GLOBIGNORE
一个文件名的模式匹配列表, 如果在通配(globbing)中匹配到的文件包含有这个列表中的某个文件, 那么这个文件将被从匹配到的结果中去掉.
$GROUPS
目前用户所属的组
这是一个当前用户的组id列表(数组), 与记录在/etc/passwd文件中的内容一样.
fhc2007@fhc2007-desktop:~/program$ id uid=1000(fhc2007) gid=1000(fhc2007) 组=4(adm),20(dialout),24(cdrom),25(floppy),29(audio),30(dip),44(video),\ 46(plugdev),107(fuse),109(lpadmin),115(admin),126(vboxusers),128(sambashare),1000(fhc2007) fhc2007@fhc2007-desktop:~/program$ echo $GROUPS 1000 fhc2007@fhc2007-desktop:~/program$ echo ${GROUPS[0]} 1000 fhc2007@fhc2007-desktop:~/program$ echo $GROUPS[1] 1000[1] fhc2007@fhc2007-desktop:~/program$ echo ${GROUPS[1]} 20 fhc2007@fhc2007-desktop:~/program$ echo ${GROUPS[2]} 24
$HOME
用户的home目录, 一般是/home/username(参见例子 9-15)
$HOSTNAME
hostname放在一个初始化脚本中, 在系统启动的时候分配一个系统名字. 然而, gethostname()函数可以用来设置这个Bash内部变量$HOSTNAME. 参见例子 9-15.
$HOSTTYPE
主机类型
就像$MACHTYPE, 用来识别系统硬件.
fhc2007@fhc2007-desktop:~/program$ echo $HOSTTYPE i486
$IFS
内部域分隔符
这个变量用来决定Bash在解释字符串时如何识别域, 或者单词边界.
$IFS 默认为空白(空格, 制表符,和换行符), 但这是可以修改的, 比如, 在分析逗号分隔的数据文件时, 就可以设置为逗号. 注意$*使用的是保存在 $IFS 中的第一个字符.
bash$ echo $IFS | cat -vte $ (Show tabs and display "$" at end-of-line.) bash$ bash -c 'set w x y z; IFS=":-;"; echo "$*"' w:x:y:z (从字符串中读取命令, 并分配参数给位置参数.)
例子 1. $IFS与空白字符
1 #!/bin/bash 2 # $IFS 处理空白与处理其他字符不同. 3 4 output_args_one_per_line() 5 { 6 for arg 7 do echo "[$arg]" 8 done 9 } 10 11 echo; echo "IFS=\" \"" 12 echo "-------" 13 14 IFS=" " 15 var=" a b c " 16 output_args_one_per_line $var # output_args_one_per_line `echo " a b c "` 17 # 18 # [a] 19 # [b] 20 # [c] 21 22 23 echo; echo "IFS=:" 24 echo "-----" 25 26 IFS=: 27 var=":a::b:c:::" # 与上边一样, 但是用" "替换了":". 28 output_args_one_per_line $var 29 # 30 # [] 31 # [a] 32 # [] 33 # [b] 34 # [c] 35 # [] 36 # [] 37 # [] 38 39 # 同样的事情也会发生在awk的"FS"域中. 40 41 # 感谢, Stephane Chazelas. 42 43 echo 44 45 exit 0
$MACHTYPE
机器类型
标识系统的硬件.
fhc2007@fhc2007-desktop:~/program$ echo $MACHTYPE i486-pc-linux-gnu
$OSTYPE
操作系统类型
fhc2007@fhc2007-desktop:~/program$ echo $OSTYPE linux-gnu
$OLDPWD
之前的工作目录(“OLD-print-working-directory”, 就是之前你所在的目录)
$PWD
工作目录(你当前所在的目录)
这与内建命令pwd作用相同.
1 #!/bin/bash 2 3 E_WRONG_DIRECTORY=73 4 5 clear # 清屏. 6 7 TargetDirectory=/home/bozo/projects/GreatAmericanNovel 8 9 cd $TargetDirectory 10 echo "Deleting stale files in $TargetDirectory." 11 12 if [ "$PWD" != "$TargetDirectory" ] 13 then # 防止偶然删错目录. 14 echo "Wrong directory!" 15 echo "In $PWD, rather than $TargetDirectory!" 16 echo "Bailing out!" 17 exit $E_WRONG_DIRECTORY 18 fi 19 20 rm -rf * 21 rm .[A-Za-z0-9]* # 删除点文件(译者注: 隐藏文件). 22 # rm -f .[^.]* ..?* 为了删除以多个点开头的文件. 23 # (shopt -s dotglob; rm -f *) 也可以. 24 # 感谢, S.C. 指出这点. 25 26 # 文件名可以包含ascii中0 - 255范围内的所有字符, 除了"/". 27 # 删除以各种诡异字符开头的文件将会作为一个练习留给大家. 28 29 # 如果必要的话, 这里预留给其他操作. 30 31 echo 32 echo "Done." 33 echo "Old files deleted in $TargetDirectory." 34 echo 35 36 37 exit 0
$PATH
可执行文件的搜索路径, 一般为/usr/bin/, /usr/X11R6/bin/, /usr/local/bin, 等等.
当给出一个命令时, shell会自动生成一张哈希(hash)表, 并且在这张哈希表中按照path变量中所列出的路径来搜索这个可执行命令. 路径会存储在环境变量中, $PATH变量本身就一个以冒号分隔的目录列表. 通常情况下, 系统都是在/etc/profile和~/.bashrc中存储$PATH的定义.(ubuntu 系统是在/etc/environment中存储$PATH的定义)
fhc2007@fhc2007-desktop:~/program$ echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/arm/3.4.1/bin fhc2007@fhc2007-desktop:~/program$ cat /etc/environment PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games" LANGUAGE="zh_CN:zh:en_US:en" LANG="zh_CN.UTF-8" CLASSPATH=.:/usr/lib/jvm/java-6-sun/lib JAVA_HOME=/usr/lib/jvm/java-6-sun fhc2007@fhc2007-desktop:~/program$ grep -C 1 'PATH' ~/.bashrc if [ -d /usr/local/arm ] ; then PATH=${PATH}:/usr/local/arm/3.4.1/bin fi
PATH=${PATH}:/opt/bin将会把目录/opt/bin附加到当前目录列表中. 在脚本中, 这是一种把目录临时添加到$PATH中的权宜之计. 当这个脚本退出时, $PATH将会恢复以前的值(一个子进程, 比如说一个脚本, 是不能够修改父进程的环境变量的, 在这里也就是不能够修改shell本身的环境变量, — 译者注: 也就是脚本所运行的这个shell).
注:当前的”工作目录”, ./, 通常是不会出现在$PATH中的, 这样做的目的是出于安全的考虑.
$PPID
进程的$PPID就是这个进程的父进程的进程ID(pid). (当然, 当前运行脚本的PID就是$$)
和 pidof 命令比较一下.
$PROMPT_COMMAND
这个变量保存了在主提示符$PS1显示之前需要执行的命令.
fhc2007@fhc2007-desktop:~/program$ grep -C 4 'PROMPT_COMMAND' ~/.bashrc # If this is an xterm set the title to user@host:dir case "$TERM" in xterm*|rxvt*) PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME}: ${PWD/$HOME/~}\007"' ;; *) ;; esac
$PS1
这是主提示符, 可以在命令行中见到它.
$PS2
第二提示符, 当你需要额外输入的时候, 你就会看到它. 默认显示”>”.
$PS3
第三提示符, 它在一个select循环中显示.
$PS4
第四提示符, 当你使用-x选项来调用脚本时, 这个提示符会出现在每行输出的开头. 默认显示”+”.
$REPLY
当没有参数变量提供给read命令的时候, 这个变量会作为默认变量提供给read命令. 也可以用于select菜单, 但是只提供所选择变量的编号, 而不是变量本身的值.
1 #!/bin/bash 2 # reply.sh 3 4 # REPLY是提供给'read'命令的默认变量. 5 6 echo 7 echo -n "What is your favorite vegetable? " 8 read 9 10 echo "Your favorite vegetable is $REPLY." 11 # 当且仅当没有变量提供给"read"命令时, 12 #+ REPLY才保存最后一个"read"命令读入的值. 13 14 echo 15 echo -n "What is your favorite fruit? " 16 read fruit 17 echo "Your favorite fruit is $fruit." 18 echo "but..." 19 echo "Value of \$REPLY is still $REPLY." 20 # $REPLY还是保存着上一个read命令的值, 21 #+ 因为变量$fruit被传入到了这个新的"read"命令中. 22 23 echo 24 25 exit 0
$UID
用户ID号
当前用户的用户标识号, 记录在/etc/passwd文件中
这是当前用户的真实id, 即使只是通过使用su命令来临时改变为另一个用户标识, 这个id也不会被改变. $UID是一个只读变量, 不能在命令行或者脚本中修改它, 并且和id内建命令很相像.
例子 2. 我是root么?
1 #!/bin/bash 2 # am-i-root.sh: 我是不是root用户? 3 4 ROOT_UID=0 # Root的$UID为0. 5 6 if [ "$UID" -eq "$ROOT_UID" ] # 只有真正的"root"才能经受得住考验? 7 then 8 echo "You are root." 9 else 10 echo "You are just an ordinary user (but mom loves you just the same)." 11 fi 12 13 exit 0 14 15 16 # ============================================= # 17 # 下边的代码不会执行, 因为脚本在上边已经退出了. 18 19 # 下边是另外一种判断root用户的方法: 20 21 ROOTUSER_NAME=root 22 23 username=`id -nu` # 或者... username=`whoami` 24 if [ "$username" = "$ROOTUSER_NAME" ] 25 then 26 echo "Rooty, toot, toot. You are root." 27 else 28 echo "You are just a regular fella." 29 fi
注:变量$ENV, $LOGNAME, $MAIL, $TERM, $USER, 和$USERNAME都不是Bash的内建变量. 然而这些变量经常在Bash的启动文件中被当作环境变量来设置. $SHELL是用户登陆shell的名字, 它可以在/etc/passwd中设置, 或者也可以在”init”脚本中设置, 并且它也不是Bash内建的.
fhc2007@fhc2007-desktop:~/program$ echo $LOGNAME fhc2007 fhc2007@fhc2007-desktop:~/program$ echo $SHELL /bin/bash fhc2007@fhc2007-desktop:~/program$ echo $TERM xterm fhc2007@fhc2007-desktop:~/program$ echo $USER fhc2007 fhc2007@fhc2007-desktop:~/program$ echo $USERNAME fhc2007