【问题标题】:Bash subcommands with arguments带有参数的 Bash 子命令
【发布时间】:2022-08-18 13:05:51
【问题描述】:

我在 bash 中有一个脚本,如下所示:

#!/usr/bin/env bash
set -e

if [[ \"$#\" == 0 ]]; then
    printhelp
    exit 1
fi

# process options
while [[ \"$1\" != \"\" ]]; do
    case \"$1\" in
    -n | --name)
        shift
        _NAME=\"$1\"
        ;;
    -i | --id)
        shift
        _ID=\"$1\"
        ;;
    -h | --help)
        printhelp
        exit 1
        ;;
    *)
        printhelp
        exit 1
        ;;
    esac
    shift
done

这工作正常,但我想添加一些将采用上述参数的“操作”。例如。用法将是:

./run.sh create --name foo --id 1234
./run.sh delete --id 1234

我无法找出正确的语法,也无法将此要求表达为能够进行搜索的适当单词。

  • 列出所有可能的参数格式。然后编写代码来理解这一点。前任。如果您总是有一个动作参数(在您的示例中创建或删除),将该动作存储在一个变量中,调用shift,其余参数可以使用您现有的代码进行处理。您也可以查看getopts :)

标签: bash arguments command


【解决方案1】:

对于子命令,您可以这样处理:

function main(){
    if (( ${#} == 0 )); then
        main_help 0;
    fi

    case ${1} in
        help | version | encrypt | decrypt )
            $1 "${@:2}";
        ;;
        * )
            echo "unknown command: $1";
            main_help 1;
            exit 1;
        ;;
    esac
}

main "$@";

然后包装每个子命令是一个函数。在每个函数内部,您将拥有独立的选项并分别对其进行解析。

例如:

function decrypt(){
    if [[ ${#} == 0 ]]; then
        decrypt_help;
    fi

    local __filename='';
    local __salt='';
    local __anchor=false;
    local error_message='';

    while [ ${#} -gt 0 ]; do
        error_message="Error: a value is needed for '$1'";
        case $1 in
            -f | --file )
                __filename=${2:?$error_message}
                shift 2;
            ;;
            -s | --salt )
                __salt=${2:?$error_message}
                shift 2;
            ;;
            -a | --anchor )
                __anchor=${2:?$error_message}
                shift 2;
            ;;
            * )
                echo "unknown option $1";
                break;
            ;;
        esac
    done

    echo filename: ${__filename:-empty};
    echo salt: ${__salt:-empty};
    echo anchor: $__anchor;

    exit 0;
}

这是我在项目中使用的完整版bash-CLI-template

演示;)

【讨论】:

    【解决方案2】:

    听起来你想要这样的东西:

    create() {
         # actiony stuff here
    }
    ACTION=$1 ; shift
    # put all your argument parsing here
    $ACTION   # call 
    

    然而,由于不同的行动可能有不同的论据,我可能会做不同的...

    create() {
        # argument parsing for create
        # then do your create stuff
    }
    ACTION=$1 ; shift
    $ACTION "$@"
    

    这会将您的所有参数传递给您的子函数,然后它可以解析自己的参数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-25
      • 2017-12-06
      • 2011-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多