如何使用任意字符串解析命令行参数

Gre*_*g B 3 bash shell-script getopts

我正在尝试创建一个脚本,该脚本具有一个选项,该选项将包含用引号括起来的任意文本(包括空格),这证明很难搜索和实现。

基本上我想要的行为是docker_build_image.sh -i "image" -v 2.0 --options "--build-arg ARG=value",这将是一个帮助脚本,用于使用我们的构建服务器简化 docker 图像的版本控制。

我最接近成功获取--options值的方法给了我 getopt 的错误,“无法识别的选项 '--build-arg ARG=value'。

完整脚本如下

#!/usr/bin/env bash
set -o errexit -o noclobber -o nounset -o pipefail
params="$(getopt -o hi:v: -l help,image:,options,output,version: --name "$0" -- "$@")"
eval set -- "$params"

show_help() {
cat << EOF
Usage: ${0##*/} [-i IMAGE] [-v VERSION] [OPTIONS...]

Builds the docker image with the Dockerfile located in the current directory.

    -i, --image         Required. Set the name of the image.
    --options           Set the additional options to pass to the build command.
    --output            (Default: stdout) Set the output file.
    -v, --version       Required. Tag the image with the version.
    -h, --help          Display this help and exit.
EOF
}

while [[ $# -gt 0 ]]
do
    case $1 in
        -h|-\?|--help)
            show_help
            exit 0
            ;;
        -i|--image)
            if [ -n "$2" ]; then
                IMAGE=$2
                shift
            else
                echo -e "ERROR: '$1' requires an argument.\n" >&2
                exit 1
            fi
            ;;        
        -v|--version)            
            if [ -n "$2" ]; then
                VERSION=$2
                shift
            else
                echo -e "ERROR: '$1' requires an argument.\n" >&2
                exit 1
            fi
            ;;
        --options)
        echo -e "OPTIONS=$2\n"
            OPTIONS=$2
        ;;
        --output)            
            if [ -n "$2" ]; then
                BUILD_OUTPUT=$2
                shift
            else
                BUILD_OUTPUT=/dev/stderr
            fi
        ;;
        --)
            shift
            break
        ;;
        *)
            echo -e "Error: $0 invalid option '$1'\nTry '$0 --help' for more information.\n" >&2
            exit 1
        ;;
    esac
shift
done

echo "IMAGE: $IMAGE"
echo "VERSION: $VERSION"
echo ""

# Grab the SHA-1 from the docker build output
ID=$(docker build ${OPTIONS} -t ${IMAGE}  . | tee $BUILD_OUTPUT | tail -1 | sed 's/.*Successfully built \(.*\)$/\1/')

# Tag our image
docker tag ${ID} ${IMAGE}:${VERSION}
docker tag ${ID} ${IMAGE}:latest
Run Code Online (Sandbox Code Playgroud)

ilk*_*chu 5

就像处理其他接受参数(imageversion)的人一样处理它。即,将标记为强制参数的冒号添加到转到 getopt 的选项字符串中,并从$2.

我认为你得到的错误来自getopt,因为它没有被告知options需要参数,所以它试图解释--build-arg ARG=value为一个长选项(它确实以双破折号开头)。

$ cat opt.sh
#!/bin/bash
params="$(getopt -o hv: -l help,options:,version: --name "$0" -- "$@")"
eval set -- "$params"

while [[ $# -gt 0 ]] ; do
    case $1 in
        -h|-\?|--help)
            echo "help"
            ;;
        -v|--version)            
            if [ -n "$2" ]; then
                echo "version: <$2>"
                shift
            fi
            ;;
        --options)            
            if [ -n "$2" ]; then
                echo "options: <$2>"
                shift
            fi
            ;;
    esac
    shift
done

$ bash opt.sh --version 123 --options blah --options "foo bar"
version: <123>
options: <blah>
options: <foo bar>
Run Code Online (Sandbox Code Playgroud)