내 스크립트에는 다음 명령이 있습니다.
set -- `getopt -q agvc:l:t:i: "$@"`
...
while [ -n "$1" ]
do
-i) TIME_GAP_BOOT=$2
shift ;;
...
sleep $TIME_GAP_BOOT
을 사용하여 스크립트를 호출하면 -i 2
오류가 발생합니다.
sleep: invalid time interval `\'2\''
내가 도대체 뭘 잘못하고있는 겁니까? 인수 형식을 올바르게 지정하려면 어떻게 해야 합니까?
답변1
bash 내장 기능은 getopts
사용하기가 훨씬 쉽습니다. 를 사용하는 경우 bash
대신 을 사용해야 합니다 getopt
.
GNU는 getopt
공백과 기타 메타 문자가 포함된 인수와 함께 작동하도록 설계되었습니다. 이를 위해서는 bash 스타일 따옴표(또는 옵션에 따라 csh 스타일 따옴표 -s
)가 포함된 결과 문자열을 생성합니다. 따옴표를 해석하도록 준비해야 하며, 이를 위해서는 를 사용해야 합니다 eval
. (bash 내장 기능이 더 낫다고 언급했나요 getopts
?)
다음 예는 getopt 배포판의 예입니다. 나는 그것과 아무 관련이 없습니다. (컴퓨터 어딘가에 있어야 합니다. 우분투와 데비안에서는 로 표시됩니다 /usr/share/doc/util-linux/examples/getopt-parse.bash
. 몇 줄만 인용하겠습니다.
# Note that we use `"$@"' to let each command-line parameter expand to a
# separate word. The quotes around `$@' are essential!
# We need TEMP as the `eval set --' would nuke the return value of getopt.
TEMP=`getopt -o ab:c:: --long a-long,b-long:,c-long:: \
-n 'example.bash' -- "$@"`
if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
# Note the quotes around `$TEMP': they are essential!
eval set -- "$TEMP"
예제의 주석이 가리키는 인용문 외에도 eval
일반적으로 눈살을 찌푸리는 을 살펴보는 것이 중요합니다.
대조적으로, bash 내장 기능은 getopts
no 를 필요로 하지 않으며 eval
매우 간단합니다. 기본적으로 표준 C 라이브러리 호출을 에뮬레이트합니다.
while getopts agvc:l:t:i: opt; do
case "$opt" in
i) TIME_GAP_BOOT=$OPTARG;;
# ...
esac
done