English 中文(简体)
KornShell - Test with variable that may be not set
原标题:

I have the following code in 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
#...

In some cases the file name not have an extension, and this causes the FILE_EXT variable to be empty, which causes the following error: ./script[37]: test: 0403-004 Specify a parameter with this command.

How should I be calling this function so that I do not get this error?

最佳回答

You should leave off the square brackets when you are testing the exit code of a function, otherwise, you ll always get "true". Also, you should quote your variable. You could put an additional test for an empty extension as shown:

FILE_EXT=${FILE#*.}

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

Edit: added test to handle filenames that end in "."

问题回答

I would do this:

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

If all you want to do is determine that the file has a numeric extension

The ${FILE_EXT:="no"} will expand to either the value of FILE_EXT, or no if FILE_EXT is null or empty.

you should use ${FILE##*.} with double "#" instead. also what do you mean the variable $FILE_EXT will be empty? if your file don t have extension, then when you do ${FILE#*.} you will get the just file name in FILE_EXT. how is it empty ?

Assuming ksh93, it should be possible to use it s own arithmetic. But we need to be careful: Just ((n)) will fail if n==0, so we test for ((n || !n)) which should always be true for any proper number.

To prevent ksh from exiting, we run the expression in a subshell ( ), adding spaces to prevent conflicts with the arithmetic expression (( ... )).

Finally, we close stderr with 2>& - to prevent any error messages from non numeric arguments, although you might want to keep them in.

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

[ -z "$1" ] will test for an empty $1, as will [ "" = "$1" ].

Or you could simply prepend a "0" to $1 (i.e, "0$1") to force it to be non-empty before checking if it is numeric (if you want empty extensions to be treated as numeric).

I had some probs to run your script (Maybe that s because im using pdksh). So I have adjusted it slightly. Try this:

#!/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




相关问题
What does it mean "to write a web service"?

I just asked a question about whether it was possible to write a web-page-checking code and run it from free web server, and one supporter answered and said that it was possible only if I run "a web ...

How can I use exit codes to run shell scripts sequentially?

Since cruise control is full of bugs that have wasted my entire week, I have decided the existing shell scripts I have are simpler and thus better. Here is what I have so far svn update /var/www/...

Dynamically building a command in bash

I am construcing a command in bash dynamically. This works fine: COMMAND="java myclass" ${COMMAND} Now I want to dynamically construct a command that redirectes the output: LOG=">> myfile.log ...

Why does Scala create a ~/tmp directory when I run a script?

When I execute a Scala script from the command line, a directory named "tmp" is created in my home directory. It is always empty, so I simply deleted it without any apparent problem. Of course, when I ...

Ivy, ant and start scripts

I have a project that uses ant to build and ivy for dependencies. I would like to generate the start scripts for my project, with the classpath, based on the dependencies configured in Ivy, ...

热门标签