0

I have got few methods (for example: addUser, addProject, addRepository). In all of them i am using curl option and they have specified local(another) variables. In first function I can have: addUser{ username user password email}

Second method has got just the name of the project and in the third method (addRepository):

addRepository{
nameOfProject
nameOfRepository}

My question is how to connect it with getopts? Shouild i do in all of the functions getopts or just make one getopts outside of any function and add parameters?

My idea was:

while getopts ":p:,:a:b:,:c:d:e:f:" option;
do
    case $option in
        #p=nameOfProject - addProject method
        p)
                p="$OPTARG"
                addProject_usage
                ;;
       #a=nameOfProject - addRepository method
       a)
               a="$OPTARG"
               addRepository_usage
                ;;
       #b=nameOfRepository - addRepository method
       b)
                b="$OPTARG"
                addRepository_usage
                ;;
        // c.d.e.f like p,a,b)

        \?) echo "Error: Invalid option -$OPTARG"
            exit 1
        ;;
    esac
done
shift $((OPTIND-1))

Of course there should be functions like:

addProject_usage() { echo "addProject: [-p <string>]" 1>&2; exit; }   
addRepository_usage() { echo "addRepository: [-a <string>] [-b <string>]" 1>&2; exit; }
addUser_usage ...

Plus instances of methods i mean - but I am not sure:

addProject -p "$p"  
addRepository -a "$a" -b "$b"
addUser ...

Am I thinking in a good way ? If not please give me some advice. I am new to scripting. Thank you!

adamos
  • 69
  • 8

1 Answers1

0

I think that passing arguments with "keys" to the BASH functions is a bad practice, because functions logic and semantic must be separated form the command line user interface logic: function is your "internal" kitchen and command-line user interface - is a "face" of your script. It is your business how to organize your code, anyway "external" representation of your script must not be affected by your internal logic.

It is better to call script with a fixed first argument, determining what the script shall do (such as ./engine.sh --addRepository), or making the symbolic links to the script, which names will be "what to do" keys:

what2do=${0##*/}
what2do=${what2do%.sh}
doAddRepository ()  {
 local repoName="$1"
 # Adding new repository with the name $repoName...
}
doAddProject ()  {
 local projName="$1"
 # Adding new project with the name $projName...
}
doAddUser ()  {
 local userName="$1"
 # Some code to add user "$userName"...
}

case $what2do in
addRepository)
  while getopts 'n:' key; do
    case $key in
      n) REPO_NAME=$OPTARG ;;
      ...
    esac
  done
  doAddRepository "$REPO_NAME" "$SOME_OTHER_ARG"
  exit $?
;;
addProject)
  while getopts 'n:' key; do
    case $key in
      n) PROJ_NAME=$OPTARG ;;
      ...
    esac
  done
  doAddProject "$PROJ_NAME" "$SOME_OTHER_ARG"
  exit $?
;;
addUser)
  while getopts 'u:' key; do
    case $key in
      u) USER_NAME=$OPTARG ;;
      ...
    esac
  done
  doAddUser "$USER_NAME" "$SOME_OTHER_ARG"
  exit $?
;;
*) 
  echo "I don't know how to $what2do. Maybe, it is NIY" >&2
  doShowUsage
  exit 1
;;
esac

Maybe this methodology is not bullet-proof, but, i hope this may be a simple and straightforward way to solve your problem in a KISS-like manner.

drvtiny
  • 705
  • 3
  • 13
  • Thank you for a lot of valuable information ! I have got question about 1st and 2nd line , what do they mean really? Second question is how i connect in case for example addRepository ... n) REPO_NAME=$OPTARG ;; -> with local repoName=$1 which i want to use in curl option i mean : curl -H "Content-Type:application/json" http://adress.com/api/v3/projects?private_token=$token -d "{ \"name\": \"$projName\" }" – adamos Aug 04 '15 at 12:34
  • If you have a script called, say, repop.sh ("repository operations") and placed at /usr/local/bin, so you can create symlink to that script with the name "addRepository.sh": ln -s repop.sh /usr/local/bin/addRepository.sh Then when you call addRepository.sh, your $0 will contain this path: /usr/local/bin/addRepository.sh If you want to get only "operation name" (addRepository), you have to get rid of directory path and extension part of the $0. what2do=${0##*/} # Get rid of directory path, what2do="addRepository.sh" what2do=${0%.sh} # Get rid of the extension part, what2do="addRepository" – drvtiny Aug 04 '15 at 15:13
  • >Second question is how i connect in case for example addRepository I m sorry, i dont understand your question... You can use variable $projName inside the double-quoted strings, so your curl commandline is correct... curl -H "Content-Type:application/json" address.com/api/v3/projects?private_token=$token -d "{ \"name\": \"$projName\" }" – drvtiny Aug 04 '15 at 15:14
  • I just want to make everything in one script without adding symbolic links to another script-files. So i have added at the top of my script: "what2do="addProject" and what2do="addRepository" " The problem is that when i want to run my script like : ./nameofscript.sh --addProject -n retewrtew -> It creates new project but it also run my second function automatically after this - i mean addRepository. I don't know why? Maybe something is wrong in getopts ? Curl option is working good because i check it in my git system. PS. You can see my code in answer 2 in this topic @drvtiny – adamos Aug 05 '15 at 07:29