Nouman Tajik Nouman Tajik - 1 month ago 6
Bash Question

CASE is behaving different in Debug and normal mode

I have wrote a script in which the "CASE" portion identify whether the byte/char entered is Lower, Upper , digit or some special character. The program runs fine but the odd thing is; When i enter the alphabet "A", and run

sh -x ./scrip "A"


Output

+ [ 1 -ne 1 ]
+ char=A
+ wc -c
+ echo A
+ NumOfChars=2
+ [ 2 -gt 2 ]
+ echo Arguments are correct in numbers
Arguments are correct in numbers
+ echo Upper case alphabet
Upper case alphabet


The output is correct (i.e. the case [A-Z] is executed

But when i execute the program is normal fashion i.e.

./script "A"


Output

Lower case alphabet


The CASE [a-z] is executed instead, why ?

The script is as follows

if [ "$#" -ne 1 ]; then
echo "Number of arguments are wrong"
exit 1;

else
char="$1"
NumOfChars=$(echo "$char" | wc -c)
if [ "$NumOfChars" -gt 2 ]; then
echo "Number of characters are greater then one"
exit 2;
else
echo " Arguments are correct in numbers ";
fi
fi
case "$char"
in

[a-z] ) echo "Lower case alphabet";;
[A-Z] ) echo "Upper case alphabet";;
[0-9] ) echo "Digit";;
* ) echo "Non AlphaNumeric characters/byte";;
esac

Answer

so you are bitten by two different problems:

  • because of the missing shebang your script will/can be executed by different shell implementations when run with sh ./script.sh resp. ./script.sh

  • the bash (which happens to execute the script when run as ./script.sh) can match A into the [a-z] for specific locales.

the fix is to specify both a shebang and the collate sequence:

#!/bin/sh
export LC_COLLATE="C"

# the rest of the script is unchanged.
if [ "$#" -ne 1 ]; then
    echo "Number of arguments are wrong"
    exit 1;

else
    char="$1"
    NumOfChars=$(echo "$char" | wc -c)
    if [ "$NumOfChars" -gt 2 ]; then
        echo "Number of characters are greater then one"
        exit 2;
    else
        echo " Arguments are correct in numbers ";
    fi
fi
case "$char"
in

[a-z] ) echo "Lower case alphabet";;
[A-Z] ) echo "Upper case alphabet";;
[0-9] ) echo "Digit";;
* )     echo "Non AlphaNumeric characters/byte";;
esac
Comments