有关shell脚本编程中test命令的用法,test命令很重要 test命令用法
功能:检查文件和比较值
当您使用左方括号而非 test 时,其后必须始终跟着一个空格、要评估的条件、一个空格和右方括号。右方括号不是任何东西的别名,而是表示所需评估参数的结束。条件两边的空格是必需的,这表示要调用 test,以区别于同样经常使用方括号的字符/模式匹配操作。
test 文件运算符
-b file 如果文件为一个块特殊文件,则为真
-c file 如果文件为一个字符特殊文件,则为真 -d file 如果文件为一个目录,则为真 -e file 如果文件存在,则为真 -f file 如果文件为一个普通文件,则为真 -g file 如果设置了文件的 SGID 位,则为真 -G file 如果文件存在且归该组所有,则为真 -k file 如果设置了文件的粘着位,则为真 -O file 如果文件存在并且归该用户所有,则为真 -p file 如果文件为一个命名管道,则为真 -r file 如果文件可读,则为真 -s file 如果文件的长度不为零,则为真 -S file 如果文件为一个套接字特殊文件,则为真 -t fd 如果 fd 是一个与终端相连的打开的文件描述符(fd 默认为 1),则为真 -u file 如果设置了文件的 SUID 位,则为真 -w file 如果文件可写,则为真 -x file 如果文件可执行,则为真
以下示例显示了此简单操作的运行情况:
$ ls -l
total 33 drwxr-xr-w 2 root root 1024 Dec 5 05:05 LST -rw-rw-rw- 1 emmett users 27360 Feb 6 07:30 evan -rwsrwsrwx 1 root root 152 Feb 6 07:32 hannah drwxr-xr-x 2 emmett users 1024 Feb 6 07:31 karen -rw------- 1 emmett users 152 Feb 6 07:29 kristin -rw-r--r-- 1 emmett users 152 Feb 6 07:29 spencer $ $ test -r evan $ echo $? 0 $ test -r walter $ echo $? 1 $
由于第一次评估为真 — 文件存在且可读 — 返回值为真,或 0。由于第二次评估的文件不存在,该值为假,返回值不为零。将值指定为零或非零很重要,因为在失败时不会始终返回 1(虽然这是通常返回的值),可能返回一个非零值。
$ [ -w evan ]
$ echo $? 0 $ [ -x evan ] $ echo $? 1 $
同样,第一个表达式为真,第二个表达式为假 — 正如返回值所指示的那样。您还可以使用以下命令将两个文件彼此进行比较:
$ [ evan -nt spencer ]
$ echo $? 0 $ [ karen -ot spencer ] $ echo $? 1 $
名为 evan 的文件比名为 spencer 的文件更新,因而评估为真。类似地,名为 karen 的文件比名为 spencer 的文件更新,因此该评估为假。
#example1
if test -n "$1" then echo "$1" fi
执行以上例子中的代码将根据 $1 是否存在给出以下结果:
$ example1 friday
friday $ $ example1 $
如果将代码更改为以下形式,则结果将相同:
#example2
if test "$1" then echo "$1" fi
如下所示:
$ example2 friday
friday $ $ example2 $
所有这些表明,通常不需要 -n,它代表默认操作。
#example3
if test -z "$1" then echo "no values were specified" fi
运行如下:
$ example3
no values were specified $ example3 friday $
如果在没有命令行参数的情况下运行该程序,而表达式评估为真,那么将执行程序块中的文本。如果在命令行中有值,则脚本退出,不执行任何操作。将评估操作放在脚本的开头非常有用,这可以在可能产生错误的进一步处理之前预先检查变量值。
$ env
LOGNAME=emmett PAGER=less SHELL=/bin/bash TERM=linux $ $ [ "$LOGNAME" = "emmett" ] $ echo $? 0 $ $ [ "$LOGNAME" = "kristin" ] $ echo $? 1 $
或者,该评估可以以脚本的形式用于决定是否运行脚本:
#example4
if [ "$LOGNAME" = "emmett" ] then echo "processing beginning" else echo "incorrect user" fi
这种方法可以用来寻找任意的值(如终端类型或 shell 类型),在允许脚本运行之前这些值必须匹配。请注意,= 或 != 运算符的优先级高于其它大多数可指定选项,且要求必须伴有表达式。因此,除了比较字符串的选项之外,= 或 != 都不能和检查某种东西(如可读文件、可执行文件或目录)的存在性的选项一起使用。
int1 -eq int2 如果 int1 等于 int2,则为真
int1 -ge int2 如果 int1 大于或等于 int2,则为真 int1 -gt int2 如果 int1 大于 int2,则为真 int1 -le int2 如果 int1 小于或等于 int2,则为真 int1 -lt int2 如果 int1 小于 int2,则为真 int1 -ne int2 如果 int1 不等于 int2,则为真
以下示例显示了一个代码段,其中在命令行中给出的值必须等于 7:
#example5
if [ $1 -eq 7 ] then echo "You've entered the magic number." else echo "You've entered the wrong number." fi
运行中:
$ example5 6
You've entered the wrong number. $ $ example5 7 You've entered the magic number. $
和字符串一样,比较的值可以是在脚本外为变量赋的值,而不必总是在命令行中提供。以下示例演示了实现这一点的一种方法:
#example6
if [ $1 -gt $number ] then echo "Sorry, but $1 is too high." else echo "$1 will work." fi $ set number=7 $ export number $ example6 8 Sorry, but 8 is too high. $ example6 7 7 will work. $
整数比较运算符最佳的用途之一是评估指定的命令行变量的数目,并判断它是否符合所要求的标准。例如,如果某个特定的命令只能在有三个或更少变量的情况下运行,
#example7 - display variables, up to three
if [ "$#" -gt 3 ] then echo "You have given too many variables." exit $# fi
只要指定三个或更少的变量,该示例脚本将正常运行(并返回值 0)。如果指定了三个以上的变量,则将显示错误消息,且例程将退出 — 同时返回与命令行中给定的变量数相等的退出代码。
#example8 - to see if it is near the end of the month#
set `date` # use backward quotes if [ "$3" -ge 21 ] then echo "It is close enough to the end of the month to proceed" else echo "This report cannot be run until after the 21st of the month" exit $3 fi
在这个例子中,设置了六个变量(通过空格彼此分开):
$1 = Fri
$2 = Feb $3 = 6 $4 = 08:56:30 $5 = EST $6 = 2004
这些值可以在脚本中使用,就像它们是在命令行中输入的一样。请注意,退出命令再次返回一个值 — 在这种情况下,返回的值是从 $3 的值中得到的日期。这一技巧在故障诊断时会非常有用 — 如果您认为脚本应该运行而没有运行,那么请查看 $? 的值。
$ env
HOME=/ LOGNAME=emmett MAIL=/usr/mail/emmett PATH=:/bin:/usr/bin:/usr/lbin TERM=linux TZ=EST5:0EDT $ $ [ "$LOGNAME" = "emmett" -a "$TERM" = "linux" ] $ echo $? 0 $ $ [ "LOGNAME" = "karen" -a "$TERM" = "linux" ] $ echo $? 1 $
在第一个评估中,两个条件都测试为真(在一个 linux 终端上登录的是 emmett),因此整个评估为真。在第二个评估中,终端检查正确但用户不正确,因此整个评估为假。
#example9
if [ "$LOGNAME" = "emmett" -o "$TERM" = "linux" ] then echo "Ready to begin." else echo "Incorrect user and terminal." fi $ env HOME=/ LOGNAME=emmett MAIL=/usr/mail/emmett PATH=:/bin:/usr/bin:/usr/lbin TERM=linux TZ=EST5:0EDT $ example9 Ready to begin. $ $ LOGNAME=karen $ example9 Ready to begin. $
在脚本第一次运行时,评估判断用户是否等于 emmett。如果发现用户等于 emmett,则脚本转至 echo 语句,并跳过其余的检查。它从不检查终端是否等于 linux,因为它只需要找到一条为真的语句就可以使整个运算为真。在脚本第二次运行时,它判断用户不是 emmett,因此它将检查并发现终端确实是 linux。由于一个条件为真,脚本现在转至 echo 命令。为了引出第二条消息,两个条件都必须为假。
#example10 - Do not let the script run over the weekend#
set `date` # use backward quotes if [ "$1" = "Sat" -o "$1" = "Sun" ] then echo "This report cannot be run over the weekend." fi
一些有用的示例
#example11 - display declining variables, up to three
if [ "$#" -gt 3 ] # see if more than three variables are given then echo "You have given more than three variables." exit fi echo $* if test -n "$2" then shift echo $* fi if test -n "$2" then shift echo $* fi
它将按以下方式执行:
$ example11 one
one $ $ example11 one two one two two $ $ example11 one two three one two three two three three $ $ example11 one two three four You have given more than three variables. $
出于检查的目的将数量限制为三个变量的原因是减少在例子中要检查的行数。一切都按部就班地进行,虽然它令人难以置信地混乱;用户因使用了超过程序依设计所能处理的变量数而得到警告,且脚本退出。如果变量数为 3 或更少,则运算的核心部分开始执行。
#example12 - display declining variables, any number
while [ "$#" -gt 0 ] do echo $* shift done $ example12 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 2 3 4 5 6 7 8 9 0 3 4 5 6 7 8 9 0 4 5 6 7 8 9 0 5 6 7 8 9 0 6 7 8 9 0 7 8 9 0 8 9 0 9 0 0
现在减少到只有 5 个有效行,且消除了第一个脚本三个变量的限制,并在运行时要更高效。
#example13
TEMP=LST cd $TEMP if [ $?-ne 0 ] then echo "Data directory could not be found." Exit fi
处理错误
$ [ "$LOGNAME" -gt 9]
test:] missing $ 请注意,错误消息指示 test 存在问题,即使使用了别名 ]。这些问题很容易发现,因为错误消息准确地将这些问题显示出来,然后您可以增加必要的空格。
|