[SOLVED] New to Bash – Execution of the script via argument leads to an error

Issue

So here my script, the basic concept I’m trying to achieve that by running command ./scripts.sh it would open a menu with options (This point is working good), and ./scripts.sh -c should run a command that defined for that argument (This point isn’t working at all).

So defining options in this way (:c:i:u:d:s:h:) leads me to

Wrong argument 'c' provided, run sh ./script.sh -h for help

Defining them in this way ("ciudsh") make arguments working, but sometimes it leads me to:

Syntax error: "(" unexpected (expecting "fi")

And *) stop working as if I’m passing the wrong argument, I see an error in which arguments are missed at all:

Wrong argument '' provided, run sh ./script.sh -h for help

So basically my question is simple, where I’m wrong in my script, I suppose I have an error in iffi clause and in my getopts, but I can’t define where, community could you please, advise me places where I’m wrong?)

#!/usr/bin/env bash

#Colors
BRed='\033[1;31m'
Green='\033[0;32m'
BCyan='\033[1;36m'
NC='\033[0m'

f1(){
}
f2(){
}
f3(){ 
}
f4(){
}
f5(){
}
f6(){
}
Help(){
}

if [ $# -eq 0 ]
then
    PS3='Please enter your choice: '
    options=("Point1" "Point2" "Point3" "Point4" "Point5" "Help" "Quit")
    select opt in "${options[@]}"
    do
        case $opt in
            "Point1")
                f1;;
            "Point2")
                f2; f3;;
            "Point3")
                f2; f4;;
            "Point4")
                f5;;
            "Point5")
                f6;;
            "Help")
                Help;;
            "Quit")
                break;;
            *) echo -e "${BRed}Selected option ${BCyan}'$REPLY'${NC} ${BRed}couldn't be find in the list of provided options${NC}"
                break;;
        esac
    done
fi

# while getopts :c:i:u:d:s:h: OPTION
while getopts "ciudsh" OPTION
do
        case $OPTION in
                c)
                    f1;;
                i)
                    f2; f3;;
                u)
                    f2; f4;;
                d)
                    f5;;
                s)
                    f6;;
                h)
                    Help;;
                *) echo -e "${BRed}Wrong argument ${BCyan}'$OPTARG'${NC} ${BRed}provided, run${NC} ${BCyan}sh $0 -h${NC} ${BRed}for help${NC}"
        esac
done

Solution

Minimal Example mysh.sh

#!/bin/bash
f1(){ echo "f1, -c";}
f2(){ echo "f2, -i";}

while getopts ":c:i:" OPTION; do
        case ${OPTION} in
                c) f1;;
                i) f2;;
                *) echo  "Wrong arguments" 
        esac
done

Well, with a minimal example like above , and using various getopts synthax we can see the following:
Using getopts ':c:i:' -> Bash expects some arguments after each parameter -c and -i
PS: The first colon makes getopts to work in silent mode. Remove it for troubleshooting – error messages to be provided in your screen

Using getopts 'ci' -> It declares to bash that parameters -c and -i take no arguments.

using getopts ':ci:' -> declares that -c will be used without arguments, but -i should be provided with an argument

Different invocations tests with bash 5.1.16

./mysh.sh -c -i           # using ':c:i:'
f1 - c                    # -i function (f2) not performed since -i is considered an argument of -c

./mysh.sh -c              # using ':c:i:'
Wrong arguments           # because the expected behavior "-parameter argument" is not met

./mysh.sh -c one -i two   # using ':c:i:'
f1, -c                    # works fine , parameter "-c" provided with argument "one" 
f2, -i                    # works fine, parameter "-i" provided with argument "two" 

./mysh.sh -c -i two       # using ':c:i:'
f1, -c                    # parameter -c considers -i to be his argument, and two is ignored

./mysh.sh -c -i           # using "ci" 
f1, -c                    # works fine, f1 function is called, no args required for -c
f2, -i                    # works fine, f2 function is called, no args required for -i

/mysh.sh -c -i            # using ':ci:'
f1, -c                    # works fine , -c is used without any arguments
Wrong arguments           # error since -i expects an argument that is not provided

./mysh.sh -c -i two       # using ':ci:'
f1, -c                    # works fine, -c used without arguments
f2, -i                    # works fine, -i used with argument two

Answered By – George Vasiliou

Answer Checked By – Senaida (BugsFixing Volunteer)

Leave a Reply

Your email address will not be published.