Chinaunix首页 | 论坛 | 博客
  • 博客访问: 512271
  • 博文数量: 119
  • 博客积分: 5054
  • 博客等级: 大校
  • 技术积分: 1305
  • 用 户 组: 普通用户
  • 注册时间: 2010-01-03 13:13
文章分类

全部博文(119)

文章存档

2011年(4)

2010年(115)

我的朋友

分类:

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
阅读(908) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~