Search code examples
bashfunctionshellreturn

Bash test of function return not working


I am trying to write a test to check if a user exists. I know there is the simple getent, which I discovered later while googling my problem (and which I will probably wind up using) but, I am now interested in solving this as an academic exercise.

I have a script, loading a second script via the source command and then executing a function from the loaded script. The goal was to run the check without spawning a subshell.

The problem I am having, is checking the return status within that called function (it, in turn, calls a second method).

My code. Initial tst.sh script:

#!/bin/sh
userName="$1"
source userExists.sh
exitIfUserExist "${userName}"
exitIfUserNotExist "${userName}"
exit 0

userExists.sh:

#!/bin/sh

#check if user exists already
checkIfUserExists()
{
    userName=$1
    echo "userName: $userName"

    while IFS= read -r line
    do
        # First, whack off everything after the username
        userNameTmp=${line%:*:*:*:*:*:*}
        echo "userNameTmp: $userNameTmp"

        # Then compare the username to that entered by the user.
        [[ $userNameTmp = "${userName}" ]] && return 0
    done </etc/passwd
    echo "Not found"

    return 2
}

exitIfUserExist()
{
    if checkIfUserExists $1 == 0
    then
      echo "Error: User ${userName} already exists"
      exit 1
    fi
    echo "end exitIfUserExist"
}

exitIfUserNotExist()
{
    checkIfUserExists $1;echo $?
    if checkIfUserExists $1 > 0
    then
        echo "Error: User ${userName} does not exist"
        exit 1
    fi
    echo "end exitIfUserNotExist"
}

Output from two tests - first with a username that exists, the second with one that does not:

[root@local_host ~]# sh t.sh bob
userName: bob
userNameTmp: root
userNameTmp: bin
userNameTmp: daemon
...
userNameTmp: rpc
userNameTmp: rpcuser
userNameTmp: nfsnobody
userNameTmp: bob
Error: User bob already exists


[root@local_host ~]# sh t.sh bobNOTTHERE
userName: bobNOTTHERE
userNameTmp: root
userNameTmp: bin
userNameTmp: daemon
...
userNameTmp: rpc
userNameTmp: rpcuser
userNameTmp: nfsnobody
userNameTmp: bob
Not found
end exitIfUserExist
userName: bobNOTTHERE
userNameTmp: root
userNameTmp: bin
userNameTmp: daemon
...
userNameTmp: rpc
userNameTmp: rpcuser
userNameTmp: nfsnobody
userNameTmp: bob
Not found
2
end exitIfUserNotExist

As can be seen the first test works, but, given the result of the second, I don't believe the if .. then test is working as I expect it to. How do I fix the tests in the "exitIf*" functions to work properly?


Solution

  • The if checkIfUserExists $1 == 0 line just call checkIfUserExists with 3 parameters ($1, "==" and "0").

    Change to: if checkIfUserExists $1

    The if instruction simply check if the command that follow is 0

    You may also change if checkIfUserExists $1 > 0 to if ! checkIfUserExists $1

    +: To do comparaison you must use one of [, [[ or (( commands/keywords