Skip to content
Advertisement

shell if statment executing even if its not true [closed]

I have created a script to create/remove local user.

code:

#!/bin/bash
# This script can create or remove a local linux user.
# --------------------------------------------------------

# Ask if the user wants to create or delete user!
read -p 'Do you want to create or delete user? (c/d) : ' TO_DO
# Account creation
if [[ "${TO_DO}" -eq 'c' ]]
then
        read -p 'Enter the username to create : ' USER_NAME
        read -p 'Enter name of account holder : ' REAL_NAME
        read -ps 'Enter the password to set : ' PASSWORD_P1
        read -ps 'Please retype password : ' PASSWORD_P2
        if [[ "${PASSWORD_P1}" -eq "${PASSWORD_P2}" ]]; then
                # Creating user.
                useradd -c "${REAL_NAME}" -m "${USER_NAME}"
                # Setting password.
                echo "${PASSWORD_P1}n${PASSWORD_P1}" | passwd "${USER_NAME}"
                # Force user to reset password on next login
                passwd -e "${USER_NAME}"
                echo 'Account created succesfully'
        else
                echo 'The password do not match.'
                exit 2
        fi
elif [[ "${TO_DO}" -eq 'd' ]]; then
        read -p 'Enter the username to delete : ' USER_NAME
        userdel -r "${USER_NAME}"
        echo 'Account deleted successfully'
else
        echo 'Please choose appropriate options!'
        exit 3
fi

WHEN I CHOOSE THE “d” OPTION. THE STATEMENTS OF “c” OPTIONS ARE EXECUTED.

Shell:

sudo ./localUserManager.sh
Do you want to create or delete user? (c/d) : d
Enter the username to create : ^C

(HERE THE OPTION TO DELETE USERNAME SHOULD COME!)

Advertisement

Answer

TL;DR: Use =, not -eq, for string comparision.


It is true. -eq is for integer comparison, and in this context, a string is treated as a parameter name to expand. If the parameter is undefined, it defaults to 0. As such, let’s say the user enters d. Then

if [[ "${TO_DO}" -eq 'c' ]]

becomes after paramter expansion

if [[ "d" -eq 'c' ]]

As neither d nor c is a defined variable, -eq expands each to 0, with the resulting comparison being

if [[ 0 -eq 0 ]]; 

which is of course true.

(To see this expansion in practice, try the following

c=0      # explicitly set c to 0
unset d  # explicitly unset d, so that it isn't defined
if [[ c -eq d ]]; then
  # c is defined, so $c -> 0 is used
  # d is not defined, so a default of 0 is used
  echo "equal"
else
  echo "not equal"
fi

Now try the same thing with c set to a non-zero value, or with both c and d set to the same value. )

If you use =, then string comparision occurs as expected.

if [[ "${TO_DO}" = 'c' ]];

becomes

if [[ "d" = 'c' ]];

which is false.

User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement