Why is my elif being treated as an else statement in my bash script?

I’m building a bash script that uses wget to GET information from a server using a REST api. I’m using getopts to parse options given to the script and then using an if statement to redirect the script correctly based on the options given. The if goes to the main body of the script (ie the wget call), the elif prints the help menu, and the else prints an error message. However my elif appears to be acting as an else statement. When I run:

>./jira -h

I get the proper response, i.e. the help menu:

----------jira options----------
Required:
-d [data/issueID]
-u [username] -> [username] is your JIRA username
-p [password] -> [password] is your JIRA password

Optional:
-q -> quiet, i.e. no output to console
-h -> help menu

However, when I run something that should give me the error message I get help menu instead:

>./jira -u jsimmons

----------jira options----------
Required:
-d [data/issueID]
-u [username] -> [username] is your JIRA username
-p [password] -> [password] is your JIRA password

Optional:
-q -> quiet, i.e. no output to console
-h -> help menu 

My script is below:

#!/bin/bash

#using getopts to parse options
while getopts ":hqd:u:p:" opt; do
        case $opt in
                h)
                        help="true"
                        ;;      
                q)
                        quiet="true"
                        ;;      
                d)
                        data=$OPTARG
                        ;;
                u)
                        username=$OPTARG
                        ;;
                p)
                        password=$OPTARG
                        ;;
                ?)
                        echo "Invalid option: -$OPTARG" >&2
                        ;;
                :)
                        echo "Option -$OPTARG requires an argument." >&2
                        ;;
        esac
done

#check if required options have been set
if [[ -n $data && -n $username && -n $password ]]; then 

        wget -q 
            --http-user=$username 
            --http-passwd=$password 
            --header="Content-Type: application/json" [URI]


        #placing issue info into variable

        response=$(< $data) 


        #using heredoc to run python script
        #python script uses regular expressions to find the value of the field 
        #customfield_10701 ie the branch version 

        output=$(python - <<EOF
import re

matchObj = re.search(
     r'(?<=customfield_10701":").*(?=","customfield_10702)',
     '$response',
     re.I
)
if(matchObj):
        print(matchObj.group())

EOF
)


        #writes branch version in .txt file

        echo $output>branchversion.txt 


        #prints the branch version if the quiet option hasn't been set 
        if [ -z $quiet ]; then
                echo "-------------------------------------------" 
                echo ""
                echo "The branch version for issue $data is:"
                cat branchversion.txt
                echo ""
        fi

        #removes file that wget creates containing all data members for the issue

        rm $data
elif [ -n $help ]; then 
        #if help option has been set    
        echo "" 
        echo "----------jira options----------"
        echo "Required:"
        echo "-d [data/issueID]"
        echo "-u [username] -> [username] is your JIRA username"
        echo "-p [password] -> [password] is your JIRA password"
        echo ""
        echo "Optional:"
        echo "-q -> quiet, i.e. no output to console"
        echo "-h -> help menu"
        echo ""
        #http GET data members for issue
else
        #if not all required options or help have been set      
        echo "Error: Missing argument(s)"
        echo "Usage: ./jira [option(s)] -d [data] -u [username] -p [password]"
        echo "" 
        echo "Try: ./jira -h for more options"
fi

Answer

the -n option checks if a string is non-zero length.

if [ ... ]; then #posix compliant condition tests

if [[ ... ]]; then #extended condition tests

It seems the extended condition tests work differently than the posix ones.

> if [ -n $unsetVar ];then echo yes ; fi
yes
>

> if [ -n "$unsetVar" ];then echo yes ; fi
>

> if [[ -n $unsetVar ]];then echo yes ; fi
>

either use the extended conditions for both [[ ... ]] or wrap your variable in quotations. Currently your elif statement is always true.

Leave a Reply

Your email address will not be published. Required fields are marked *