Comparing variables in shell scripts

56,886

Solution 1

After if, you need a shell command, like anywhere else. $X = $Y is parsed as a shell command, meaning $X is interpreted as a command name (provided that the value of the variable is a single word).

You can use the [ command (also available as test) or the [[ … ]] special syntax to compare two variables. Note that you need spaces on the inside of the brackets: the brackets are a separate token in the shell syntax.

if [ "$X" = "$Y" ]; then …

or

if [[ "$X" = "$Y" ]]; then …

[ … ] works in any shell, [[ … ]] only in ksh, bash and zsh.

Note that you need double quotes around the variables¹. If you leave off the quotes, then the variable is split into multiple words and each word is interpreted as a wildcard pattern. This doesn't happen inside [[ … ]], but the right-hand side of = is interpreted as a wildcard pattern there too. Always put double quotes around variable substitutions (unless you want the value of the variable to be used as a list of filename matching patterns, rather than as a string).

¹ Except on $X the [[ … ]] syntax.

Solution 2

This KornShell (ksh) script should work:

soExample.ksh

#!/bin/ksh 

#Initialize Variables
X="a"
Y="a"

#Function to create File with Input
#Params: 1}
stest(){
    if [ "${X}" == "${Y}" ]; then
        echo "they're the same"
    else 
        echo "they're not the same"
    fi
}

#-----------
#---Main----
#-----------
echo "Starting: ${PWD}/${0} with Input Parameters: {1: ${1} {2: ${2} {3: ${3}"
stest #function call#
echo "completed"
echo "Exiting: ${PWD}/${0}"

Output :

user@foo:/tmp $ ksh soExample.ksh
Starting: /tmp/soExample.ksh with Input Parameters: {1:  {2:  {3:
they're not the same
completed
Exiting: /tmp/soExample.ksh

ksh version:

user@foo:/tmp $ echo $KSH_VERSION
@(#)MIRBSD KSH R48 2013/08/16
Share:
56,886
user3047191
Author by

user3047191

Updated on July 28, 2022

Comments

  • user3047191
    user3047191 almost 2 years

    I have got a project that involves shell scripts and comparing values/variables within them. I have looked here and elsewhere on comparing variables and I have tried all the various examples given but I am running into something that is not as advertised. OS is Solaris10

    I have created the following script as a learning experience-

    #!/bin/ksh
    
    stest()
    {
    if $X = $Y
    then echo they're the same
    else echo they're notthe same
    fi
    }
    
    
    X=a
    Y=a
    
    stest
    
    echo completed
    

    I keep getting some variation of the following-

    using shell sh or ksh-

    #./test.sh
    ./test.sh[2]: a:  not found
    completed
    

    using shell bash-

    #./test.sh
    ./test.sh: line 5: a: command not found
    completed
    

    I have tried enclosing the if $X = $Y line in brackets and double brackets and I get back

    [a:  not found  
    

    or

    [[a:  not found
    

    If I change the variables X and Y to the numeral "1" I get the same thing-

    ./test.sh[2]: 1:  not found
    

    I have tried enclosing things in single quotes, double quotes & backwards quotes.

    Any help is appreciated.

  • tripleee
    tripleee over 10 years
    You should double-quote all variable interpolations. If $X contains whitespace you will start seeing error messages or, worse yet, user input being run as code.
  • javaPlease42
    javaPlease42 over 10 years
    @tripleee Good point, code updated. Do you have a reference where it says double-quoteing all variable interpolations is a ksh best practice?
  • tripleee
    tripleee over 10 years
    Nothing specifically for ksh, but it's fairly obvious when you know how the shell works. Unless you specifically require whitespace splitting and wildcard expansion of a variable's value, it needs to be quoted.
  • user10089632
    user10089632 about 6 years
    This endorses this solution for people who come here seeking an answer, I just don't have ksh to test it. And the spaces are important.