#!/bin/sh
CONFIG_DIR="/var/opt/SUNWldm/"
read option
if [ $option -eq 9 ]; then
ret=1
elif [ -e ${CONFIG_DIR}file.xml.${option} ]; then
echo "TRUE"
fi
我在 while 循环中使用了上述代码来显示选项列表。不幸的是,我在语句方面遇到了问题elfi
。
从:如果初学者如果文件存在,-e 返回 true。
我已经仔细检查了语法,甚至在调试模式下运行脚本(我放在set -x
该脚本的开头,可以看到 中的替换if
已正确完成,如内联所示:
+ [ 201301271355 -eq 9 ]
+ [ -e /var/opt/SUNWldm/file.xml.201301271355 ]
./ldm_recover.sh: test: argument expected
到目前为止我一直在寻找,但还没有找到失败的原因,你知道我做错了什么吗?
答案1
Bourne shell 有点像古董。 Solaris 版本没有(又名)内置-e
函数的运算符,该运算符是在 Bourne shell 生命周期的后期引入的,并被 POSIX 所珍视。test
[
作为解决方法,您可以用来-f
测试常规文件是否存在,或者-r
如果您对不可读的文件不感兴趣。
更好的是,更改#!/bin/sh
为#!/usr/xpg4/bin/sh
或#!/bin/ksh
以获得 POSIX shell。
请注意,这[ $option -eq 9 ]
可能是不正确的:-eq
是一个数字比较运算符,但$option
并不是真正的数字 - 它是一个日期。在 32 位机器上,当201301271355
被解释为数字时,它会以 2 32为模。碰巧的是,21 世纪没有任何日期非常接近 0 modulo 2 32,但依赖于此是非常脆弱的。做这个[ "$option" = 9 ]
代替。
作为一般的 shell 编程原则,始终在变量和命令替换两边加上双引号:"$foo"
,"$(foo)"
。如果不这样做,shell 会在每个空白字符处拆分结果,并将每个结果单词视为文件名通配符模式。因此,$foo
仅当 的值foo
不包含任何空格或时,不受保护才是安全的\[?*
。谨慎行事并始终使用双引号(除非您打算进行拆分和模式匹配)。
或者它是一个从未移植到 Bourne 的 ksh 添加内容?我不知道。
答案2
嗯,这比我想的要容易:
看来-e
the 的运算符if
没有在 bourne shell (sh) 中定义,而仅在 bourne Again shell (bash) 中定义。
我替换了if [ -e ...
byif [ -r ...
并且它可以工作。