Bash 接受多个参数的 CLI

Bash CLI that accepts multiple arguments

我正在尝试创建自定义 CLI,但我 运行 遇到了问题。

这是我的代码。

#!/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  in
            --create)
                shift
                case  in
                    -domain) 
                        DOMAIN_NAME=""; 
                        shift 
                        ;;
                    -ssl)
                        INSTALL_SSL=""; 
                        shift 
                        ;;
                    -wp|--wp) 
                        INSTALL_WP=""; 
                        shift 
                        ;;
                    *)
                    echo -e "Unknown parameter passed: ";
                    __help_menu
                    exit
                    ;;
                esac
                ;;
            --delete)
                shift
                case  in
                    -domain) 
                        DOMAIN_NAME=""; 
                        shift 
                        ;;
                    -ssl)
                        DELETE_SSL=""; 
                        shift 
                        ;;
                    *)
                    echo -e "Unknown parameter passed: ";
                    __help_menu
                    exit
                    ;;
                esac
                ;;
            --help) __help_menu; exit ;;
        *) echo -e "Unknown parameter passed: "; exit 1 ;;
        
        esac
        shift
    done
}

__cli "$@"

if [ "" == "--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

当我 运行 ./cli.sh --create -domain example.com 它工作正常。但是当我 运行 ./cli.sh --create -domain example.com -ssl yes 它说传递了未知参数:-ssl。我哪里做错了?

另一个问题:

./cli.sh --create -domain hello.com 替换为 foo --create -domain hello.com 的最佳方法是什么,这样我就可以在终端的任何位置使用 CLI。

如何使用 GNU getopt 简化命令行解析的示例:

#! /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 "" in
    --domain) DOMAIN=""; shift 2;;
    --ssl)    SSL="";    shift 2;;
    --wp)     WP="";     shift 2;;
    --) shift; break;;
    *)  break;;
  esac
done

COMMAND=; shift

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

用法:

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

--ssl--wp 的默认值为“是”。

@ceving

我想我得到了我想要的东西。我将进一步探索 getop。我做了一个简单的调整。有效。

#!/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 "" in
        --domain) DOMAIN=""; shift 2;;
        --ssl)    SSL="";    shift 2;;
        --wp)     WP="";     shift 2;;
        --) shift; break;;
        *)  break;;
    esac
    done

    COMMAND=; shift

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

__cli "$@"

顺便说一句,为了用 foo create --domain example.com 替换 ./cli.sh create --domain example.com,我应该添加一个指向 ./cli.sh 文件的别名还是有更好的方法?