全部博文(584)
分类: LINUX
2010-01-06 15:08:24
摘自《高级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