임의의 문자열을 사용하여 명령줄 인수를 구문 분석하는 방법

임의의 문자열을 사용하여 명령줄 인수를 구문 분석하는 방법

따옴표로 묶인 임의의 텍스트(공백 포함)를 포함하는 옵션이 있는 스크립트를 만들려고 하는데 검색하고 구현하기가 어렵습니다.

기본적으로 내가 원하는 동작은 docker_build_image.sh -i "image" -v 2.0 --options "--build-arg ARG=value"이것이 빌드 서버를 사용하여 도커 이미지의 버전 제어를 단순화하는 도우미 스크립트가 되는 것입니다.

값 을 성공적으로 얻는 데 가장 가까운 것은 --optionsgetopt에서 "인식할 수 없는 옵션 '--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

답변1

"향상된" getopt(util-linux 또는 Busybox에서)를 사용하는 것으로 보인다면 인수( 및 )를 options사용하여 다른 작업처럼 진행하세요 . 즉, getopt로 이동하는 옵션 문자열에 필수 매개변수를 표시하는 콜론을 추가한 다음 값을 선택합니다 .imageversion$2

나는 당신이 받고있는 오류가 인수가 필요하다는 getopt말을 듣지 않았기 때문에 에서 비롯된 것이라고 생각합니다 options. 그래서 그것을 긴 옵션으로 해석하려고합니다 --build-arg ARG=value(이중 대시로 시작합니다).

$ cat opt.sh
#!/bin/bash
getopt -T
if [ "$?" -ne 4 ]; then
    echo "wrong version of 'getopt' installed, exiting..." >&2
    exit 1
fi 
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>

관련 정보