LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Software (https://www.linuxquestions.org/questions/linux-software-2/)
-   -   calling multiple functions from within if statement - cannot get it to work (https://www.linuxquestions.org/questions/linux-software-2/calling-multiple-functions-from-within-if-statement-cannot-get-it-to-work-4175735978/)

Grobe 04-13-2024 09:08 AM

calling multiple functions from within if statement - cannot get it to work
 
Hi.

I have this sample/training bash file that is supposed to check username and computer name.

There is something making this bash file not working correctly. But I'm not able to figure exact what that is.

I've put comments in the script to explain the problem(s)

Code:

#!/bin/bash

username=$(whoami)
thisComputerHostname=$(hostname)

function staticControlUsername () {
        if [ $username != 'grobe' ]; then
                echo 'WARNING: Pohibited from running, not logged in as correct user'
                echo 'Your login name ' $username
                return 0
        else
                echo 'INFO: User granted to run script (test 1)'
                echo 'Your login name ' $username
                return 1
        fi
}

function staticControlMachineName () {
        if [ $thisComputerHostname != 'resirkulert-Acer' ]; then
                echo 'WARNING: Pohibited from running, the computer name are incorrect'
                echo 'Current computer name:' $thisComputerHostname
                return 0
        else
                echo 'INFO: User granted to run script (test 2)'
                echo 'Name of current computer:' $thisComputerHostname
                return 1
        fi
}


# Those function call gives error when executed
#if [ staticControlUsername -a staticControlMachineName ]; then
#if [ staticControlUsername -eq 1 -a staticControlMachineName -eq 1 ]; then
#if [ [ staticControlUsername ] -a [ staticControlMachineName ] ]; then

# This returns 'Looks good' when executed, but doesn't print echo from within the functions, indicating
# that the functions isn't actually executed.'
if [ staticControlUsername ] && [ staticControlMachineName ] ; then
        echo 'Looks good'
else
        echo 'At least one test failed...'
fi


boughtonp 04-13-2024 09:21 AM


 
"[ expression ]" is an alias for "test expression" which evaluates an expression, not a command.

To evaluate the exit status of a command, remove the brackets.

See:
//www.gnu.org/software/bash/manual/html_node/Conditional-Constructs.html
//www.gnu.org/software/bash/manual/html_node/Bourne-Shell-Builtins.html#index-test

Also, using ShellCheck to identify issues is always a good idea.


Grobe 04-13-2024 10:25 AM

Quote:

Originally Posted by boughtonp (Post 6495684)
"[ expression ]" is an alias for "test expression" which evaluates an expression, not a command.

To evaluate the exit status of a command, remove the brackets.

See:
//www.gnu.org/software/bash/manual/html_node/Conditional-Constructs.html
//www.gnu.org/software/bash/manual/html_node/Bourne-Shell-Builtins.html#index-test

Also, using ShellCheck to identify issues is always a good idea.


Thanks, I did the shellcheck.net but this only gave corrections on quotes.


It seems to work better now, but it still doesn't work as intended:

Updated code (only line 38 is edited)
Code:

#!/bin/bash

username=$(whoami)
thisComputerHostname=$(hostname)

function staticControlUsername () {
        if [ $username != 'grobe' ]; then
                echo 'WARNING: Pohibited from running, not logged in as correct user'
                echo 'Your login name ' $username
                return 0
        else
                echo 'INFO: User granted to run script (test 1)'
                echo 'Your login name ' $username
                return 1
        fi
}

function staticControlMachineName () {
        if [ $thisComputerHostname != 'resirkulert-Acer' ]; then
                echo 'WARNING: Pohibited from running, the computer name are incorrect'
                echo 'Current computer name:' $thisComputerHostname
                return 0
        else
                echo 'INFO: User granted to run script (test 2)'
                echo 'Name of current computer:' $thisComputerHostname
                return 1
        fi
}


# Those function call gives error when executed
#if [ staticControlUsername -a staticControlMachineName ]; then
#if [ staticControlUsername -eq 1 -a staticControlMachineName -eq 1 ]; then
#if [ [ staticControlUsername ] -a [ staticControlMachineName ] ]; then

# This returns 'Looks good' when executed, but doesn't print echo from within the functions, indicating
# that the functions isn't actually executed.'
if staticControlUsername && staticControlMachineName ; then
        echo 'Looks good'
else
        echo 'At least one test failed...'
fi

On my end, both username and computer name is tested correct, but the script still runs wrong - details:
  • Line 12 and 13 executes normally
  • Line 41 wrongly execute - Line 39 is expected to execute but doesn't
  • Line 24 and 25 expected to execute but doesn't - neither does line 20/21.
The script seems to run as if the if the function staticControlUsername was returning 0, but it shouldn't.

MadeInGermany 04-13-2024 10:26 AM

In other words, a function is like a command.
And the if takes a command.
Code:

if staticControlUsername && staticControlMachineName
then
  ...
fi

Further, in the shell 0 is the success return code, 1 is a failure.
You can as well return the exit status of a true/false command.
Code:

true; return
or
Code:

false; return

boughtonp 04-13-2024 10:38 AM

Quote:

Originally Posted by Grobe (Post 6495698)
The script seems to run as if the if the function staticControlUsername was returning 0, but it shouldn't.

Re-read the first piece of documentation I linked, paying careful attention to the terms "zero" and "non-zero", specifically:
Quote:

The test-commands list is executed, and if its return status is zero, the consequent-commands list is executed.
,..
If ‘else alternate-consequents’ is present, and the final command in the final if or elif clause has a non-zero exit status, then alternate-consequents is executed.
With exit statuses, zero means success, non-zero means failure.


Grobe 04-13-2024 10:51 AM

Quote:

Originally Posted by MadeInGermany (Post 6495699)
Further, in the shell 0 is the success return code, 1 is a failure.
You can as well return the exit status of a true/false command.

Ah, THIS is where I was thinking wrong about the concept. Thank you very much for that info, after I inverted all the return codes in functions, the script behaved as expected.

So the misconception I have is coming from earlier (a life before Linux) I played around with Authohotkey script and the wbs script that was including in MS os. In those script languages, any call to a function, where the call is part of an if-statement, is normally treated as true for any number or non-zero strings. And this use for function calls therefore follows other rules.

murugesandins 04-16-2024 05:48 AM

Code:

#!/bin/bash
#I thought of sharing my thought.
#I always use full path
if [[ ! -f /usr/bin/whoami ]]
then
        echo /usr/bin/whoami file not found
elif [[ ! -f /usr/bin/hostname ]]
then
        echo /usr/bin/hostname file not found
else
        #you can use export if using this variable using awk/gawk/gawk.exe
        username=$(/usr/bin/whoami)
        thisComputerHostname=$(/usr/bin/hostname)
        #if some other included before this line other script could have defined alias. Hence using unalias and unset -f
        unalias staticControlUsername >/dev/null 2>&1
        unset -f staticControlUsername
        function staticControlUsername()
        {
                if [[ "$username" != "grobe" ]]
                then
                        echo "WARNING: Pohibited from running, not logged in as correct user"
                        echo "Your login name  $username"
                        #return 1 fail result
                        return 1
                else
                        echo "INFO: User granted to run script (test 1)"
                        echo "Your login name  $username"
                        #return 0 pass result
                        return 0
                fi
        }
        unalias staticControlMachineName >/dev/null 2>&1
        unset -f staticControlMachineName
        function staticControlMachineName()
        {
                #Better to use [[ .. ]] to have multiple conditional readable condition
                if [[ "$thisComputerHostname" != "resirkulert-Acer" ]]
                then
                        echo "WARNING: Pohibited from running, the computer name are incorrect"
                        echo "Current computer name: $thisComputerHostname"
                        return 0
                else
                        echo "INFO: User granted to run script (test 2)"
                        echo "Name of current computer: $thisComputerHostname"
                        return 1
                fi
        }
        # ========= OLD COMMENTS SHARED BY YOU =========
        # Those function call gives error when executed
        #if [[ staticControlUsername -a staticControlMachineName ]; then
        #if [[ staticControlUsername -eq 1 -a staticControlMachineName -eq 1 ]; then
        #if [[ staticControlUsername -a staticControlMachineName ]]; then
        # This returns "Looks good" when executed, but doesn't print echo from within the functions, indicating
        # that the functions isn't actually executed.
        # ========= OLD COMMENTS SHARED BY YOU =========
        if [[ 0 -eq $# ]]
        then
                staticControlUsername
        else
                staticControlUsername $@
        fi
        staticControlUsernameRet=$?
        if [[ 0 -eq $staticControlUsernameRet ]]
        then
                if [[ 0 -eq $# ]]
                then
                        staticControlMachineName
                else
                        staticControlMachineName $@
                fi
                staticControlMachineNameRet=$?
                if [[ 0 -eq $staticControlMachineNameRet ]]
                then
                        echo "Looks good"
                else
                        echo "staticControlMachineName test failed..."
                fi
        else
                echo "staticControlUsername test failed..."
        fi
fi
# COMMENTS
# Example at return values using cygwin bash.exe at Windows 11:
# $ /usr/bin/ls.exe /usr/bin/ls
# $ echo $?
# 0
# $ /usr/bin/ls.exe invalidfile.txt >/dev/null 2>&1
# $ echo $?
# 2
# $ /usr/bin/file.exe /cygdrive/c/Users/murugesan_openssl | /usr/bin/grep file
# $ echo $?
# 1
# $ /usr/bin/file /cygdrive/c/Users/murugesan_openssl | /usr/bin/grep.exe directory
# /cygdrive/c/Users/murugesan_openssl: directory
# $ echo $?
# 0


Grobe 04-16-2024 12:32 PM

Putting the function declaration within an if statement is new for me. I think I must try to wrap my mind around this now

pan64 04-16-2024 12:55 PM

Quote:

Originally Posted by Grobe (Post 6496383)
Putting the function declaration within an if statement is new for me. I think I must try to wrap my mind around this now

forget it, it is not a good idea. That will only make the script unmaintainable.

murugesandins 04-16-2024 01:05 PM

Quote:

Originally Posted by Grobe (Post 6496383)
Putting the function declaration within an if statement is new for me. I think I must try to wrap my mind around this now

I agree this is difficult for 1/2/3/few months during startup.
I am having printpassbook.sh shell script from 2003 till now.
Before modification I used to take a backup of that file
After modification I used to gzip that backup file.
printpassbook.sh used to display:
1) my post office transactions (incoming/outgoing +/- four days from today
2) available balance that I can withdraw excluding recurring deposit amount and MAB
3) MIS interest I am going to receive tomorrow and day after tomorrow
4) my total salary from MIS at post office for current month
5) waiting day/month/years at RD/MIS accounts.
6) displaying related colors based on date/waiting day/month/years.

Remember to take backup before modification for maintenance.

chrism01 04-17-2024 01:37 AM

I'm with pan64 - don't do that ;)


All times are GMT -5. The time now is 05:58 AM.