나는 튜토리얼을 따랐다.여기사용 방법을 알아보세요 getopts
. 사용자가 제공한 모든 옵션을 올바르게 실행할 수 있습니다. 그런데 이제는 옵션이 제공되지 않을 때 기본 옵션을 실행하고 싶습니다.
예를 들어:
while getopts ":hr" opt; do
case $opt in
h )
show_help;
exit 1
;;
r )
echo "Default option executed"
;;
esac
done
따라서 사용자가 또는 을 제공하면 -h
해당 -r
명령이 실행되어야 하지만(그렇습니다) 이러한 옵션이 제공되지 않으면 -r
기본적으로 실행되어야 합니다. 이것을 달성할 수 있는 방법이 있나요?
고쳐 쓰다
cas's
제안 사항을 시도 하고 이를 *)
내 getopts
기능에 통합했지만 아무 일도 일어나지 않는 것 같습니다.
while getopts ":hr" opt; do
case $opt in
h )
show_help;
exit 1
;;
r )
echo "Default option executed"
;;
\? )
echo error "Invalid option: -$OPTARG" >&2
exit 1
;;
: )
echo error "Option -$OPTARG requires an argument."
exit 1
;;
* )
echo "Default option executed"
;;
esac
done
이 코드에 문제가 있나요?
답변1
구문 분석할 옵션이 없으면 case
문이 실행되지 않으므로 문에 기본 옵션을 추가해도 도움이 되지 않습니다. getopts
쉘 변수를 사용하여 얼마나 많은 옵션을 처리하는지 확인할 수 있습니다 OPTIND
. 에서 help getopts
:
Each time it is invoked, getopts will place the next option in the
shell variable $name, initializing name if it does not exist, and
the index of the next argument to be processed into the shell
variable OPTIND. OPTIND is initialized to 1 each time the shell or
a shell script is invoked.
따라서 OPTIND
1이면 옵션이 처리되지 않습니다. 루프 뒤에 다음을 추가합니다 while
.
if (( $OPTIND == 1 )); then
echo "Default option"
fi
답변2
while
옵션이 제공되지 않으면 Bash의 getopts는 $opt를 "?"로 설정하여 루프를 종료합니다. 스크립트에서 이 상황을 확인하려면 다음 과 유사한 루프 if
뒤에 절을 추가하세요 .while
if [ "$opt" = "?" ]
then
echo "Default option executed (by default)"
fi
참고로 다음을 참조하세요.Bourne Shell 내장 함수
답변3
getopts
루프를 사용하여 전달된 인수를 기반으로 변수를 설정합니다. 그런 다음 다음 변수에 대해 조치를 취하십시오.
#!/bin/sh
# Defaults:
do_help=0
do_r=0
while getopts "hr" opt; do
case $opt in
h) do_help=1 ;;
r) do_r=1 ;;
*) echo 'Error in command line parsing' >&2
exit 1
esac
done
if [ "$do_help" -eq 1 ]; then
show_help
exit
fi
printf 'Default option executed (r=%d)\n' "$do_r"
나는 0이 아닌 종료 상태(도움을 요청하는 것은 오류가 아님)를 사용하는 대신 -h
사용 시(실패하지 않는 한) 성공적으로 코드를 종료하도록 선택했습니다 .show_help
실행하세요:
$ sh script.sh -r
Default option executed (r=1)
$ sh script.sh
Default option executed (r=0)
$ sh script.sh -h
script.sh[24]: show_help: not found
이는 명령줄 구문 분석 코드를 나머지 스크립트 논리와 분리하는 이점이 있습니다.
또한 실제 구문 분석 루프를 짧게 유지하면서 루프 후에 기본적인 온전성 검사를 수행할 수 있습니다. 예를 들어:
# command line parsing loop above here
if [ "$do_help" -eq 1 ] && [ "$do_r" -eq 1 ]; then
echo 'Options -h and -r are mutually exclusive' >&2
exit 1
fi
# code that acts on user-supplied options below
답변4
내가 아는 한, r은 인수를 기대하지 않습니다. 논리적으로 r은 무슨 일이 일어나더라도 동일한 방식으로 수행됩니다.
getopts 절에서 r 관련 명령을 가져와 실행하도록 하겠습니다. 나는 이것이 귀하의 요구 사항에 충분하다고 믿습니다. 즉, "done" 문 뒤에 echo 문을 배치하세요.
호환성이나 다른 이유로 r을 원하는 경우 getopts에서 r을 스텁으로 유지할 수 있습니다.
0으로 설정된 변수를 스위치로 추가할 수도 있습니다. r 이외의 옵션을 선택하면 변수를 1로 변경하는 줄이 있습니다. 명령문을 완성한 후 "변수가 0이면 기본 명령을 실행합니다"라고 쓸 수 있습니다.
나는 Cas의 답변이 가장 좋다고 생각합니다. 댓글을 달고 싶지만 권한이 없습니다. 나는 그의 아이디어를 기반으로 할 것입니다. 이는 Cas가 제안한 것과 동일하지만 명령이 하나만 있고(그래서 동일한 명령이 두 개가 있어서 나중에 실수하는 일이 없음) -H 외에 추가로 사용할 수 있는 가능성을 제공합니다.
DEF="Default command executed"
while getopts ":hr" opt;
do case $opt in
h) show_help;
exit 1 ;;
r) echo "$DEF" ;;
*) echo "$DEF" ;;
esac
done