이러한 입력 중 하나라도 작동하기를 바랍니다. 즉, -n
옵션 자체는 선택 사항입니다. 저는 이미 이 작업을 수행하는 방법을 알고 있습니다. 하지만 상단에 선택적인 매개 변수가 있을 수 있습니다. 인수가 지정되지 않으면 대체 값이 적용됩니다.
command -n 100
command -n
전자 입력 유형이나 후자만 작동하도록 할 수 있지만 둘 다 작동할 수는 없습니다.
HAS_NICE_THINGS=0
NICE_THINGS=50 # default value.
while getopts n: option; do
#while getopts n option; do # NICE_THINGS would always be that default value.
#while getopts nn: option; do # same.
case "${option}" in
n)
HAS_NICE_THINGS=1
if [[ ! -z "${OPTARG}" ]] && (( "${OPTARG}" > 0 )) && (( "${OPTARG}" <= 100 )); then
NICE_THINGS=${OPTARG}
fi;;
esac
done
# error message:
# option requires an argument -- n
내 스크립트에 부울이 필요한지 완전히 확신할 수는 없지만, 지금까지는 HAS_NICE_THINGS
만약을 대비해 하나( )를 기록하고 있습니다.
나의 궁극적인 목표는 최종적으로 이미지를 저장할 때 JPG 품질을 설정하는 것입니다. 하지만 이 구조가 다른 곳에서도 유용할 것이라고 생각합니다.
나는 Ubuntu 18.04.5
및 을 사용하고 있습니다 GNU bash, version 4.4.20(1)-release (x86_64-pc-linux-gnu)
.
답변1
Bash/POSIX에 비해 그리 스마트하지는 않지만 getopts
util-linux 또는 Busybox에서 "enhancement"(s 없이)를 사용하여 getopt
이를 수행 할 수 있습니다. (그게 전부입니다. 특히 많은 "전통적인" getopt
구현도 깨졌기 때문입니다. 공백도 깨졌습니다.)
매뉴얼 페이지에는 다음과 같이 나와 있습니다 getopts
.
선택적 문자열인식할 옵션 문자를 포함합니다. 문자 뒤에 콜론이 오면 옵션에는 인수가 있어야 하며 공백으로 구분해야 합니다.
선택적 옵션 매개변수에 대한 언급이 없습니다.
물론 기본값이 아닌 값을 제공하는 또 다른 선택적 옵션을 사용할 수도 있습니다. 예를 들어, -n
매개변수를 사용하지 않고 좋은 기능만 활성화하고, -N <arg>
매개변수를 사용하고 좋은 기능을 활성화하고 값을 설정해 보겠습니다.
예를 들어 다음과 같습니다.
#!/bin/bash
HAS_NICE_THINGS=0
NICE_THINGS_VALUE=50
while getopts nN: option; do
case "${option}" in
n)
HAS_NICE_THINGS=1
shift;;
N)
HAS_NICE_THINGS=1
NICE_THINGS_VALUE=$OPTARG
shift; shift;;
esac
done
if [ "$HAS_NICE_THINGS" = 1 ]; then
echo "nice things enabled with value $NICE_THINGS_VALUE"
fi
줄게
$ bash nice-getotps.sh -n
nice things enabled with value 50
$ bash nice-getopts.sh -N42
nice things enabled with value 42
util-linux는 getopt
이중 콜론 구문을 사용하여 선택적 옵션 매개변수를 얻습니다. 사용하기가 약간 어색하고 처리가 필요 eval
하지만 올바르게 수행하면 제대로 작동하는 것 같습니다.
-o shortopts
[...]의 각 짧은 옵션 문자지름길필수 매개변수가 있음을 나타내는 콜론과 선택적 매개변수가 있음을 나타내는 두 개의 콜론이 뒤에 올 수 있습니다.
스크립트를 사용하여 원래 값을 인쇄하면 제대로 작동하는지 확인할 수 있습니다( getopt-optional.sh
).
#!/bin/bash
getopt -T
if [ "$?" -ne 4 ]; then
echo "wrong version of 'getopt' installed, exiting..." >&2
exit 1
fi
params="$(getopt -o an:: -- "$@")"
eval set -- "$params"
while [ "$#" -gt 0 ]; do
case "$1" in
-n)
echo "option -n with arg '$2'"
shift 2;;
-a)
echo "option -a"
shift;;
--)
shift
break;;
*)
echo "something else: '$1'"
shift;;
esac
done
echo "remaining arguments ($#):"
printf "<%s> " "$@"
echo
우리는 얻었다
$ bash getopt-optional.sh -n -a
option -n with arg ''
option -a
remaining arguments (0):
<>
$ bash getopt-optional.sh -n'blah blah' -a
-n 'blah blah' -a --
option -n with arg 'blah blah'
option -a
remaining arguments (0):
<>
-n
빈 매개변수로 표시 할 매개변수가 없습니다 .
어떤 경우에도 명시적인 null 인수를 전달할 수 없습니다. 옵션 인수는 옵션 자체와 동일한 명령줄 인수 내에 있어야 하고 -n
따옴표를 제거한 후의 인수와 동일해야 하기 때문입니다. 이는 선택적 옵션 인수를 사용하기 어렵게 만듭니다. 왜냐하면 옵션 인수 없이 옵션으로 처리되고 옵션 이 아닌 일반 명령줄 인수가 따라오기 때문에 -n""
사용해야 하기 때문입니다 . 이는 필수 옵션 매개변수를 사용할 때 발생하는 것과 다릅니다.-nx
-n x
-n
x
-n
자세히 getopt
알아보기이 Stackoverflow 답변도착하다Bash에서 명령줄 인수를 구문 분석하는 방법은 무엇입니까?
getopt
이는 Linux 시스템에서는 일반적이지만 다른 시스템에서는 일반적이지 않을 수 있는 특정 구현으로 제한되는 것 같습니다 . 다른 구현에서는 getopt
인수에 공백을 지원하지 않을 수도 있습니다(프로그램은 공백을 따옴표로 묶어야 합니다). "향상된" util-linux 버전에는 -T
해당 특정 버전이 설치되어 있는지 테스트할 수 있는 옵션이 있습니다. 다음은 제한 사항과 주의 사항에 대한 설명입니다 getopt
.
getopt, getopts 또는 수동 구문 분석 - 짧은 옵션과 긴 옵션을 모두 지원하려면 무엇을 사용해야 합니까?
또한 getopt
이는 표준 도구가 아닙니다 getopts
.
답변2
-a
선택적 옵션 매개변수와 함께 옵션을 제공한다고 가정해 보겠습니다 . 옵션을 사용하면 쉘에 쉘 변수가 설정되어야 하지만, 옵션 인수가 제공되지 않으면 a_opt
값으로 설정되어야 하고, 그렇지 않으면 일반적인 값으로 설정되어야 합니다.$a_default
$OPTARG
매개변수 없이 사용할 시기를 결정하려면 -a
다음 두 가지 경우가 있습니다.
- 사용자가 사용하고 있는 옵션 인수가
getopts
실제로 다른 옵션 중 하나라고 생각하거나 - 이
-a
옵션은 목록 명령줄 끝에 사용됩니다(getopts
이 경우 일반적으로 누락된 옵션에 대한 오류가 생성됩니다).
첫 번째 상황은 $OPTARG
다른 옵션 중 하나와 유사한지 확인하여 처리됩니다. 그렇다면 기본값을 사용하고, 그렇지 않으면 기본값을 사용하십시오 $OPTARG
. 기본값을 사용할 때 나중에 옵션 구문 분석을 다시 시작해야 합니다 -a
. 이는 일부 인수( OPTIND
그 중 -1개)를 제거하고 1로 재설정한 다음 위치 인수 목록 앞에 OPTIND
추가하는 것을 의미합니다.$OPTARG
-a
이것이 의미하는 바는 옵션 중 하나로 보이는 인수를 사용할 수 없다는 것입니다 .
두 번째 경우를 처리하는 방법은 옵션 문자열의 첫 번째 문자를 getopts
be 로 만드는 것입니다 :
. 여기에는 두 가지 효과가 있습니다.
getopts
더 이상 자체적으로 오류가 발생하지 않습니다.- 옵션 인수가 필요한 옵션이 옵션 인수를 얻지 못하는 경우 옵션 이름이 에 배치되고
$OPTARG
옵션:
과 함께 사용되는 옵션 변수에 배치됩니다getopts
.
이는 :
일반적으로 사용되는 옵션 구문 분석 문 case
에 사례를 추가하여 사용자가 명령줄 끝에 해당 문을 사용했는지 여부 $OPTARG
를 테스트 할 수 있음을 의미합니다.a
-a
암호:
#!/usr/local/bin/bash
a_default='A default value'
d_opt=false
while getopts :a:b:c:d opt; do
case $opt in
a)
case $OPTARG in
-[a-d-]*)
shift "$(( OPTIND - 1 ))"
OPTIND=1
set -- "$OPTARG" "$@"
a_opt=$a_default
;;
*)
a_opt=$OPTARG
esac
;;
b) b_opt=$OPTARG ;;
c) c_opt=$OPTARG ;;
d) d_opt=true ;;
:)
if [ "$OPTARG" = a ]; then
a_opt=$a_default
else
printf '%s: option requires an argument -- %s\n' \
"$0" "$OPTARG" >&2
exit 1
fi
;;
*) printf '%s: generic option parsing error\n' "$0" >&2
exit 1
esac
done
shift "$(( OPTIND - 1 ))"
printf '%s = "%s"\n' \
'a_opt' "${a_opt-(Not set)}" \
'b_opt' "${b_opt-(Not set)}" \
'c_opt' "${c_opt-(Not set)}" \
'd_opt' "${d_opt-(Not set)}"
if [ "$#" -gt 0 ]; then
printf 'Extra argument: "%s"\n' "$@"
fi
시험:
a_opt
-a
옵션 없이 사용하면 기본값을 얻습니다.
$ ./script -a
a_opt = "A default value"
b_opt = "(Not set)"
c_opt = "(Not set)"
d_opt = "false"
a_opt
-a
사용하지 않으면 다음 값을 얻을 수 없습니다.
$ ./script -b bval
a_opt = "(Not set)"
b_opt = "bval"
c_opt = "(Not set)"
d_opt = "false"
a_opt
options 인수를 제공하여 평소와 같이 값을 제공 할 수 있습니다 -a
.
$ ./script -da aval -c cval
a_opt = "aval"
b_opt = "(Not set)"
c_opt = "cval"
d_opt = "true"
다음을 사용하여 옵션 구문 분석을 종료 할 수 있습니다 --
.
$ ./script -d -a -- aval -c cval hello world
a_opt = "A default value"
b_opt = "(Not set)"
c_opt = "(Not set)"
d_opt = "true"
Extra argument: "aval"
Extra argument: "-c"
Extra argument: "cval"
Extra argument: "hello"
Extra argument: "world"