IF statement vs logical operator not working as expected

Viewed 62

I am writing a simple function to check on three different files existence in which it should return "yes" if ALL three files exist and "Partially" if one or more file exists and "no" if none of the three exist.

The function is called IsPortalDown and it has a case switch; NodeOne is the one in use at this point.

Here's my function

function IsPortalDown() {
  case "$1" in
    NodeOne )
    if [[ -f $wpsdmgr ]] && [[ -f $wpsnodeagent ]] && [[ ! -f $wpsserver ]];
    then
      echo "Yes"
    elif [[ ! -f $wpsdmgr ]] || [[ ! -f $wpsnodeagent ]] || [[ ! -f $wpsserver ]];
    then
      echo "Partially"
    else
      echo "No"
    fi;
      ;;
    NodeTwo )
      ;;
  esac
}

A few constants are defined to clean things up a little bit. See below

PortalProfileLogsDir=/opt/IBM/WebSphere/wp_profile/logs
WPSDMGRProfileLogsDir=/opt/IBM/WebSphere/AppServer/profiles/dmgr01/logs
wpsdmgr=$WPSDMGRProfileLogsDir/dmgr/dmgr.pid
wpsnodeagent=$PortalProfileLogsDir/nodeagent/nodeagent.pid
wpsserver=$PortalProfileLogsDir/WebSphere_Portal/WebSphere_Portal.pid

Here's how I call the function and expected result below.

IsPortalDown NodeOne

If all three files exist the output shall be as below

[wpssrvr@tstdydalbpt0101 dmgr]$ IsPortalDown NodeOne 
Yes

If one of the three files exist the output shall be as below

[wpssrvr@tstdydalbpt0101 dmgr]$ IsPortalDown NodeOne 
Partially

If none of the three files exist the output shall be as below

[wpssrvr@tstdydalbpt0101 dmgr]$ IsPortalDown NodeOne 
No

My issue now is that if one of the three files or all three files does not exist I am constantly getting Yes instead of Partially.

Any help is appreciated. Thanks

2 Answers

This might simplify the logic somewhat: count the number of files that exist:

nfiles=0
for file in "$wpsdmgr" "$wpsnodeagent" "$wpsserver"; do
    [[ -f $file ]] && ((++nfiles))
done

case $nfiles in
    3) echo Yes ;;
    0) echo No ;;
    *) echo Partially ;;
esac

Your if logic is just completely wrong. Put this in your function instead:

local result=(No Partially Partially Yes) i= c=

for i in file1 file2 file3; do
    [[ -f "$i" ]] && ((c++))
done

echo "${result[c]}"

Remember, that -f fails for (existing) directories, device files, etc. Consider if -r (readable) or -e (exists) would be more appropriate.

You can also choose one of the following, to appropriately return success (zero) or failure (non-zero) of your function (I tested them all):

# If at least one exists, return 0 (success), otherwise return 1 (failure).
(($c)); return $?

# If all exist, return 0, otherwise return 1.
return $(( -( (c-5) / (c-4) - 2) ))

# Similar to above, but return the number of files that didn't exist (0 = success).
return $((3-c))
Related