KornShell - Test with variable that may be not set

14,449

Solution 1

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 "."

Solution 2

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 ?

Solution 3

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>& -
}

Solution 4

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.

Share:
14,449
C. Ross
Author by

C. Ross

I'm a professional software engineer, with a background in Android, C#, and Java systems throughout the stack, and experience in several industries.

Updated on June 04, 2022

Comments

  • C. Ross
    C. Ross almost 2 years

    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?