Home > Blockchain >  Bash CLI that accepts multiple arguments
Bash CLI that accepts multiple arguments

Time:01-25

I am trying to create a custom CLI & I ran into a problem.

Here is my code.

#!/bin/bash

# Function definations.
__help_menu() {

      echo -e ""
      echo -e "======================="
      echo -e "THESE ARE THE AVAILABLE COMMANDS:"
      echo -e ""
      echo -e "⟹   ./cli.sh --create -domain example.com"
      echo -e "⟹   ./cli.sh --create -domain example.com -ssl <no|yes>"
      echo -e "⟹   ./cli.sh --create -domain example.com -ssl <yes|no> -wp <yes|no>"
      echo -e "⟹   ./cli.sh --delete -domain example.com"
      echo -e "⟹   ./cli.sh --delete -domain example.com -ssl <yes|no>"
      echo -e "======================="
      echo -e ""
}

__create() {

    # Do something. I got this.
    echo -e "I got this"
}

__delete() {

    # Do something. I got this.
    echo -e "I got this"
}

__cli() {

    # Run while loop.
    while [[ "$#" -gt 0 ]]; do
        case $1 in
            --create)
                shift
                case $1 in
                    -domain) 
                        DOMAIN_NAME="$2"; 
                        shift 
                        ;;
                    -ssl)
                        INSTALL_SSL="$2"; 
                        shift 
                        ;;
                    -wp|--wp) 
                        INSTALL_WP="$2"; 
                        shift 
                        ;;
                    *)
                    echo -e "Unknown parameter passed: $1";
                    __help_menu
                    exit
                    ;;
                esac
                ;;
            --delete)
                shift
                case $1 in
                    -domain) 
                        DOMAIN_NAME="$2"; 
                        shift 
                        ;;
                    -ssl)
                        DELETE_SSL="$2"; 
                        shift 
                        ;;
                    *)
                    echo -e "Unknown parameter passed: $1";
                    __help_menu
                    exit
                    ;;
                esac
                ;;
            --help) __help_menu; exit ;;
        *) echo -e "Unknown parameter passed: $1"; exit 1 ;;
        
        esac
        shift
    done
}

__cli "$@"

if [ "$1" == "--create" ]; then

    echo -e "Command is to create a new site."
    echo -e "Domain name: $DOMAIN_NAME"
    echo -e "Install SSL: $INSTALL_SSL"
    echo -e "Install WP: $INSTALL_WP"
    echo -e ""
fi

When I run ./cli.sh --create -domain example.com it's working fine. But when I run ./cli.sh --create -domain example.com -ssl yes it says Unknown parameter passed: -ssl. Where am I doing a mistake?

Another question:

What is the best way to replace ./cli.sh --create -domain hello.com with foo --create -domain hello.com so I can use the CLI from anywhere in the terminal.

CodePudding user response:

Example how to use GNU getopt to simplify command line parsing:

#! /bin/bash

options=$(getopt -q -o '' -l domain:,ssl:,wp: -- "$@") || {
  printf 'ERROR: Invalid argument\n' >&2
  exit 1
}
eval set -- "$options"

while true; do
  case "$1" in
    --domain) DOMAIN="$2"; shift 2;;
    --ssl)    SSL="$2";    shift 2;;
    --wp)     WP="$2";     shift 2;;
    --) shift; break;;
    *)  break;;
  esac
done

COMMAND=$1; shift

case ${COMMAND:?missing} in
  create|delete)
    echo "$COMMAND" "${DOMAIN:?missing}" "${SSL:-yes}" "${WP:-yes}";;
  *)
    printf 'COMMAND: invalid\n' >&2; exit 1;;
esac

Usage:

./cli.sh create --domain http://example.com

The default for --ssl and --wp is "yes".

CodePudding user response:

@ceving

I think I got what I was looking for. I'll explore getop more. I made a simple tweak. It works.

#!/bin/bash

__help_menu() {

      echo -e ""
      echo -e "======================="
      echo -e "THESE ARE THE AVAILABLE COMMANDS:"
      echo -e ""
      echo -e "⟹   ./cli.sh create --domain example.com"
      echo -e "⟹   ./cli.sh create --domain example.com --ssl <no|yes>"
      echo -e "⟹   ./cli.sh create --domain example.com --ssl <yes|no> --wp <yes|no>"
      echo -e "⟹   ./cli.sh delete --domain example.com"
      echo -e "⟹   ./cli.sh delete --domain example.com --ssl <yes|no>"
      echo -e "======================="
      echo -e ""
}

__handle_create () {

    if [ "$COMMAND" = "create" ]; then

        if [ "$SSL" = "no" ] && [ "$WP" = "no" ]; then
            __create $DOMAIN
        else
           INSTALL_SSL=$SSL
           INSTALL_WP=$WP   
            __create $DOMAIN $INSTALL_SSL $INSTALL_WP
        fi 
    fi
}

__create() {

    echo -e ""
    if [ "$DOMAIN" != "" ]; then
        echo -e "DOMAIN is: $DOMAIN"
    fi
    if [ "$SSL" != "" ]; then
        echo -e "INSTALL SSL: $INSTALL_SSL"
    fi
    if [ "$WP" != "" ]; then
        echo -e "INSTALL WP: $INSTALL_WP"
    fi
    echo -e ""
}

__handle_delete() {

    if [ "$COMMAND" = "delete" ]; then

        if [ "$SSL" = "no" ]; then
            __delete $DOMAIN
        else
            __delete $DOMAIN $SSL
        fi 
    fi
}

__delete() {

    echo -e ""
    echo -e "DOMAIN is: $DOMAIN"
    echo -e "DELETE SSL: $SSL"
    echo -e ""
}

__cli() {

    options=$(getopt -q -o '' -l domain:,ssl:,wp: -- "$@") || {

    echo -e 'ERROR: Invalid argument\n' >&2
    exit 1
    }

    eval set -- "$options"

    while true; do
    case "$1" in
        --domain) DOMAIN="$2"; shift 2;;
        --ssl)    SSL="$2";    shift 2;;
        --wp)     WP="$2";     shift 2;;
        --) shift; break;;
        *)  break;;
    esac
    done

    COMMAND=$1; shift

    case ${COMMAND:?missing} in
        create )
            __handle_create $@
            ;;
        delete )
            handle_delete $@
            ;;
        help )
            __help_menu
            ;;
        *)
        __help_menu
        ;;
    esac
}

__cli "$@"

BTW, in order to replace ./cli.sh create --domain example.com with foo create --domain example.com should I add an Alias that points to ./cli.sh file or is there a better way?

  •  Tags:  
  • Related