bourne shell if

bourne shell if
#!/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

嗯,这比我想的要容易:

看来-ethe 的运算符if没有在 bourne shell (sh) 中定义,而仅在 bourne Again shell (bash) 中定义。

我替换了if [ -e ...byif [ -r ...并且它可以工作。

相关内容