【问题标题】:KornShell - Test with variable that may be not setKornShell - 使用可能未设置的变量进行测试
【发布时间】:2010-12-25 20:29:37
【问题描述】:

我在 KornShell (ksh) 中有以下代码:

FAILURE=1
SUCCESS=0

isNumeric(){

    if [ -n "$1" ]; then
        case $1 in
            *[!0-9]* | "")  return $FAILURE;
                       * )  return $SUCCESS;
        esac;
    else
        return $FAILURE;
    fi;
}

#...
FILE_EXT=${FILE#*.}

if [ isNumeric ${FILE_EXT} ]; then
    echo "Numbered file."
fi
#...

在某些情况下,文件名没有扩展名,这会导致FILE_EXT 变量为空,从而导致以下错误: ./script[37]: test: 0403-004 Specify a parameter with this command.

我应该如何调用这个函数,以免出现这个错误?

【问题讨论】:

  • 我希望整个文件名都在 FILE_EXT 中而不是什么都没有,除非文件名以 '.' 结尾

标签: shell unix scripting ksh


【解决方案1】:

当你测试一个函数的退出代码时,你应该去掉方括号,否则,你总是会得到“真”。此外,您应该引用您的变量。您可以对空扩展名进行额外测试,如下所示:

FILE_EXT=${FILE#*.}

if isNumeric "${FILE_EXT}" &&
    [ "${FILE_EXT}" != "${FILE}" -a "${FILE_EXT}" != "" ]
then
    echo "Numbered file."
fi

编辑:添加了测试以处理以“.”结尾的文件名

【讨论】:

  • 这不包括以'.'结尾的文件
  • 是的,你应该引用你的变量。
【解决方案2】:

我会这样做:

if [ isNumeric ${FILE_EXT:="no"} ]; then
    echo "Numbered file."
fi

如果您只想确定文件具有数字扩展名

${FILE_EXT:="no"} 将扩展为 FILE_EXT 的值,如果 FILE_EXT 为 null 或为空,则为“no”。

【讨论】:

  • 对于仅包含数字的文件名的误报,因为如果根本没有点,$FILE_EXT 将包含完整的文件名。
【解决方案3】:

您应该使用带有双“#”的${FILE##*.}。还有你是什么意思变量 $FILE_EXT 将为空?如果您的文件没有扩展名,那么当您执行${FILE#*.} 时,您将在FILE_EXT 中获得正确的文件名。怎么是空的?

【讨论】:

    【解决方案4】:

    假设 ksh93,应该可以使用它自己的算术。但是我们需要注意: 如果 n==0,只有 ((n)) 会失败,因此我们测试 ((n || !n)),对于任何正确的数字,它都应该始终为真。

    为了防止 ksh 退出,我们在子 shell ( ) 中运行表达式,添加空格以防止与算术表达式 (( ... )) 发生冲突。

    最后,我们用 '2>& -' 关闭 stderr 以防止来自非数字参数的任何错误消息,尽管您可能希望保留它们。

    function isNumeric { 
      (
        typeset n=${1:?}
        ((n||!n))
      ) 2>& -
    }
    

    【讨论】:

      【解决方案5】:

      [ -z "$1" ] 将测试一个空的$1[ "" = "$1" ] 也是如此。

      或者您可以简单地在$1(即"0$1")前面加上一个“0”,以在检查它是否为数字之前强制它为非空(如果您希望将空扩展名视为数字)。

      【讨论】:

        【解决方案6】:

        我在运行您的脚本时遇到了一些问题(可能是因为我正在使用 pdksh)。所以我稍微调整了一下。试试这个:

        #!/usr/bin/ksh
        
        FILE=$1
        FAILURE=1
        SUCCESS=0
        
        isNumeric ()
        {
            if [ -n "$1" ]
            then
                case $1 in
                    *[!0-9]* | "")
                        echo "$1 not a number"
                        return $FAILURE
                    ;;
                               * )
                        echo "$1 is a number"
                        return $SUCCESS
                    ;;
                esac
            else
                echo "parameter is empty"
                return $FAILURE
            fi
        }
        
        #...
        FILE_EXT=${FILE#*.}
        echo $FILE_EXT
        
        isNumeric "${FILE_EXT}"
        if [ "$?" = "0" ]
        then
            echo "Numbered file."
        fi
        

        【讨论】:

          猜你喜欢
          • 2011-01-18
          • 2010-09-24
          • 2010-10-26
          • 1970-01-01
          • 2016-08-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多