专注各种脚本编程
Baidu
加入收藏夹
本站内容有下面分类知识,欢迎您的到来^_^
shell相关:指令篇 基础篇 脚本欣赏 编程实例 shell问问 shell视频教程 技巧篇 水平测试 E文资料 vi编辑器 高级Bash脚本编程指南
其他:mysql perl c语言 oracle
当前位置:| 主页>高级Bash脚本编程指南>

9.1. 内部变量(2)

百度收藏 QQ搜藏

例子 9-5. 我是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
 

--------------------------------------------------------------------------------

也参考一下例子 2-3.

 变量$ENV, $LOGNAME, $MAIL, $TERM, $USER, 和$USERNAME$ENV,都不是Bash内建的。然而常常在Bash的启动文件之一里作为环境变量设置。$SHELL变量是用户的登录shell的名字,它可以在/etc/passwd文件里设置或是在一个“初始化”的脚本里设置,并且它同样不是Bash内建的。

 tcsh% echo $LOGNAME
 bozo
 tcsh% echo $SHELL
 /bin/tcsh
 tcsh% echo $TERM
 rxvt
 
 bash$ echo $LOGNAME
 bozo
 bash$ echo $SHELL
 /bin/tcsh
 bash$ echo $TERM
 rxvt
       
 

 

位置参数

$0, $1, $2,等等

位置参数由命令行传给脚本或传给一个函数,或设置(set)给一个变量(参考例子 4-5和例子 11-15)

$#
命令行参数[2]或者是位置参数的数量(参考例子 33-2)

$*
所有的位置参数都被当成单个单元。

 "$*"必须被引号引起来。
 

$@
和$*相同,但每个参数都是一个引起的字符串。那是说,参数都是没有被解析或扩展,是完整无缺地被传递的。这是说在参数列表中的每一个参数都被看作是一个单独的单元。

 当然,"$@"应该被引号引起来。
 


--------------------------------------------------------------------------------

例子 9-6. arglist: 用$*和$@列出参数来

   1 #!/bin/bash
   2 # arglist.sh
   3 # 用几个参数来运行这个脚本,比如说"one two three".
   4
   5 E_BADARGS=65
   6
   7 if [ ! -n "$1" ]
   8 then
   9   echo "Usage: `basename $0` argument1 argument2 etc."
  10   exit $E_BADARGS
  11 fi 
  12
  13 echo
  14
  15 index=1          # 初始计数.
  16
  17 echo "Listing args with \"\$*\":"
  18 for arg in "$*"  # 如果"$*"没有被引号引起来,会完全不能工作.
  19 do
  20   echo "Arg #$index = $arg"
  21   let "index+=1"
  22 done             # $* sees all arguments as single word.
  23 echo "Entire arg list seen as single word."
  24
  25 echo
  26
  27 index=1          # Reset count.
  28                  # What happens if you forget to do this?
  29
  30 echo "Listing args with \"\$@\":"
  31 for arg in "$@"
  32 do
  33   echo "Arg #$index = $arg"
  34   let "index+=1"
  35 done             # $@ sees arguments as separate words.
  36 echo "Arg list seen as separate words."
  37
  38 echo
  39
  40 index=1          # Reset count.
  41
  42 echo "Listing args with \$* (unquoted):"
  43 for arg in $*
  44 do
  45   echo "Arg #$index = $arg"
  46   let "index+=1"
  47 done             # Unquoted $* sees arguments as separate words.
  48 echo "Arg list seen as separate words."
  49
  50 exit 0
 

--------------------------------------------------------------------------------

在一个shift命令的后面,变量$@会保存除掉先前参数列表的位置参数$1后剩下的命令行参数。    1 #!/bin/bash
   2 # 以./scriptname 1 2 3 4 5执行
   3
   4 echo "$@"    # 1 2 3 4 5
   5 shift
   6 echo "$@"    # 2 3 4 5
   7 shift
   8 echo "$@"    # 3 4 5
   9
  10 # 每次"shift"后会丢掉$1.
  11 # 然后"$@"保存剩下的参数。
 


The $@ special parameter finds use as a tool for filtering input into shell scripts. The cat "$@" construction accepts input to a script either from stdin or from files given as parameters to the script. See Example 12-21 and Example 12-22.

 依赖于$IFS变量的设置,$*和$@变量有时会表现不一致的令人迷惑的行为。
 


--------------------------------------------------------------------------------

例子 9-7. $*和$@的不一致

   1 #!/bin/bash
   2
   3 #  Erratic behavior of the "$*" and "$@" internal Bash variables,
   4 #+ depending on whether they are quoted or not.
   5 #  Inconsistent handling of word splitting and linefeeds.
   6
   7
   8 set -- "First one" "second" "third:one" "" "Fifth: :one"
   9 # Setting the script arguments, $1, $2, etc.
  10
  11 echo
  12
  13 echo 'IFS unchanged, using "$*"'
  14 c=0
  15 for i in "$*"               # quoted
  16 do echo "$((c+=1)): [$i]"   # This line remains the same in every instance.
  17                             # Echo args.
  18 done
  19 echo ---
  20
  21 echo 'IFS unchanged, using $*'
  22 c=0
  23 for i in $*                 # unquoted
  24 do echo "$((c+=1)): [$i]"
  25 done
  26 echo ---
  27
  28 echo 'IFS unchanged, using "$@"'
  29 c=0
  30 for i in "$@"
  31 do echo "$((c+=1)): [$i]"
  32 done
  33 echo ---
  34
  35 echo 'IFS unchanged, using $@'
  36 c=0
  37 for i in $@
  38 do echo "$((c+=1)): [$i]"
  39 done
  40 echo ---
  41
  42 IFS=:
  43 echo 'IFS=":", using "$*"'
  44 c=0
  45 for i in "$*"
  46 do echo "$((c+=1)): [$i]"
  47 done
  48 echo ---
  49
  50 echo 'IFS=":", using $*'
  51 c=0
  52 for i in $*
  53 do echo "$((c+=1)): [$i]"
  54 done
  55 echo ---
  56
  57 var=$*
  58 echo 'IFS=":", using "$var" (var=$*)'
  59 c=0
  60 for i in "$var"
  61 do echo "$((c+=1)): [$i]"
  62 done
  63 echo ---
  64
  65 echo 'IFS=":", using $var (var=$*)'
  66 c=0
  67 for i in $var
  68 do echo "$((c+=1)): [$i]"
  69 done
  70 echo ---
  71
  72 var="$*"
  73 echo 'IFS=":", using $var (var="$*")'
  74 c=0
  75 for i in $var
  76 do echo "$((c+=1)): [$i]"
  77 done
  78 echo ---
  79
  80 echo 'IFS=":", using "$var" (var="$*")'
  81 c=0
  82 for i in "$var"
  83 do echo "$((c+=1)): [$i]"
  84 done
  85 echo ---
  86
  87 echo 'IFS=":", using "$@"'
  88 c=0
  89 for i in "$@"
  90 do echo "$((c+=1)): [$i]"
  91 done
  92 echo ---
  93
  94 echo 'IFS=":", using $@'
  95 c=0
  96 for i in $@
  97 do echo "$((c+=1)): [$i]"
  98 done
  99 echo ---
 100
 101 var=$@
 102 echo 'IFS=":", using $var (var=$@)'
 103 c=0
 104 for i in $var
 105 do echo "$((c+=1)): [$i]"
 106 done
 107 echo ---
 108
 109 echo 'IFS=":", using "$var" (var=$@)'
 110 c=0
 111 for i in "$var"
 112 do echo "$((c+=1)): [$i]"
 113 done
 114 echo ---
 115
 116 var="$@"
 117 echo 'IFS=":", using "$var" (var="$@")'
 118 c=0
 119 for i in "$var"
 120 do echo "$((c+=1)): [$i]"
 121 done
 122 echo ---
 123
 124 echo 'IFS=":", using $var (var="$@")'
 125 c=0
 126 for i in $var
 127 do echo "$((c+=1)): [$i]"
 128 done
 129
 130 echo
 131
 132 # Try this script with ksh or zsh -y.
 133
 134 exit 0
 135
 136 # 这个脚本由Stephane Chazelas所写,
 137 # 并由本书作者做了少些修改.
 

--------------------------------------------------------------------------------

 $@和$*仅仅在被双引号引住时不同。
 


--------------------------------------------------------------------------------

例子 9-8. 当$IFS为空时的$*和$@

   1 #!/bin/bash
   2
   3 #  如果$IFS被设置,但值是空的,
   4 #+ 则"$*"和"$@"不会像希望的那样显示位置参数。
   5
   6 mecho ()       # 显示位置参数.
   7 {
   8 echo "$1,$2,$3";
   9 }
  10
  11
  12 IFS=""         # 设置了,但值是空的.
  13 set a b c      # 位置参数.
  14
  15 mecho "$*"     # abc,,
  16 mecho $*       # a,b,c
  17
  18 mecho $@       # a,b,c
  19 mecho "$@"     # a,b,c
  20
  21 #  当$IFS为空时,
  22 #+ $*和$@的行为依赖于Bash或是sh正在运行.
  23 #  因此在一个脚本里使用这种“特性”是失策的。
  24
  25
  26 # 多谢Stephane Chazelas.
  27
  28 exit 0
 

--------------------------------------------------------------------------------

其它的特殊参数

$-
(使用set命令)传给脚本的标记. 参考例子 11-15.

 这原本是一个ksh的结构,但被Bash采纳了,并且不幸的是,它看上去好像不能真正的在Bash脚本中工作。一个可能有用的地方是脚本用来测试自己本身是否是一个交互式的。
 

$!
在后台运行的最后一个作业的PID(进程ID)。

   1 LOG=$0.log
   2
   3 COMMAND1="sleep 100"
   4
   5 echo "Logging PIDs background commands for script: $0" >> "$LOG"
   6 # So they can be monitored, and killed as necessary.
   7 echo >> "$LOG"
   8
   9 # Logging commands.
  10
  11 echo -n "PID of \"$COMMAND1\":  " >> "$LOG"
  12 ${COMMAND1} &
  13 echo $! >> "$LOG"
  14 # PID of "sleep 100":  1506
  15
  16 # 多谢Jacques Lederer的建议.
 


   1 possibly_hanging_job & { sleep ${TIMEOUT}; eval 'kill -9 $!' &> /dev/null; }
   2 # 强迫一个出错的程序结束退出.
   3 # 这很有用,尤其在初始化脚本中.
   4
   5 # 多谢Sylvain Fourmanoit发现"!"变量创造性的用处.
 


$_
保存前一个命令最后一个参数的变量值。


--------------------------------------------------------------------------------

例子 9-9. 下划线变量

   1 #!/bin/bash
   2
   3 echo $_              # /bin/bash
   4                      # 只需调用/bin/bash来运行这个脚本.
   5
   6 du >/dev/null        # 从命令行里没有输出.
   7 echo $_              # du
   8
   9 ls -al >/dev/null    # 从命令行里没有输出.
  10 echo $_              # -al  (它是最后的参数)
  11
  12 :
  13 echo $_              # :
 

--------------------------------------------------------------------------------

$?
一个命令,函数或脚本自身的退出状态码(参考例子 23-7)

$$
脚本本身的进程PID。$$变量常被用于脚本中生成一个"唯一的"临时文件名(参考例子 A-13, 例子 29-6, 例子 12-28, 和例子 11-25). 这通常比调用mktemp还要简单。


[1] 当然,当前运行的脚本的PID就是$$。
 
[2] 术语"argument"和"parameter"常常可互相替换。在这个文档的上下文中,它们有相同的意思,即它们是传递给脚本或函数的变量。[译者注:翻译时,译者已经把这两个术语依据上下文意思都做了适当的翻译].

上一篇:9.1. 内部变量(1) 下一篇:9.2. 操作字符串(1)

power by soyo123 2007-2008