살펴보고 있어요optparse 라이브러리옵션 구문 분석 의 경우 bash
특히 생성된 코드의 다음 지점을 참조하세요.
params=""
while [ $# -ne 0 ]; do
param="$1"
shift
case "$param" in
--my-long-flag)
params="$params -m";;
--another-flag)
params="$params -a";;
"-?"|--help)
usage
exit 0;;
*)
if [[ "$param" == --* ]]; then
echo -e "Unrecognized long option: $param"
usage
exit 1
fi
params="$params \"$param\"";; ##### THIS LINE
esac
done
eval set -- "$params" ##### AND THIS LINE
# then a typical while getopts loop
여기에 사용하는 진짜 이유가 있나요 eval
? 입력eval
~인 것 같다적절한 소독을 실시합니다. 그러나 다음을 사용하는 것도 똑같이 효과적이지 않을까요?
params=()
# ...
--my-long-flag)
params+=("-m");;
--another-flag)
params+=("-a");;
# ...
params+=("$param");;
# ...
set -- "${params[@]}"
나에게는 이것이 더 깨끗해 보인다.
실제로 배열에서 직접 (또는 ? params
를 사용하지 않고도 ) 대신 을 사용하여 옵션을 구문 분석할 수 있습니까?set
while getopts "ma" option "${params[@]}"; do
while getopts "ma" option; do
답변1
문제는 "~해야 한다평가 세트 대신 bash 배열 사용 - "$params"? ",정답은예!.
스크립트에서 eval에 대한 입력은 분명히 다음과 같습니다.아니요제대로 소독하세요. 노력하다
yourscript '`xterm`'
백틱이 작은따옴표로 올바르게 묶여 있어도 xterm이 시작되는 것을 볼 수 있습니다. (비교
echo '`xterm`'
xterm이 시작되지 않습니다. )
버그를 보존하면서 수정하는 것은 eval
매우 어렵습니다. 줄을 바꿔도
params="$params \"$param\"";;
도착하다
params="$params '$param'";;
아무 소용이 없습니다: 지금
yourscript '`xterm`'
xterm은 더 이상 시작되지 않지만
yourscript \'' `xterm` '\'
아직.
답변2
당신은하지 않습니다필요여기에서 배열을 사용하십시오 bash
(그러나 기분이 더 좋다면 사용하십시오).
수행 방법은 다음과 같습니다 /bin/sh
.
#!/bin/sh
for arg do
shift
case "$arg" in
--my-long-flag)
set -- "$@" -m ;;
--another-flag)
set -- "$@" -a ;;
"-?"|--help)
usage
exit 0 ;;
--*)
printf 'Unrecognised long option: %s\n' "$arg" >$2
usage
exit 1 ;;
*)
set -- "$@" "$arg"
esac
done
이는 bash
다른 변수를 도입할 필요가 없기 때문에 배열 솔루션(개인 의견)보다 깨끗합니다. 또한 각 명령줄 인수를 다음과 같이 유지하므로 표시된 자동 생성 코드보다 낫습니다.별도의 프로젝트존재하다 "$@"
. 이는 사용자가 따옴표로 묶인 공백 문자가 포함된 매개변수를 전달할 수 있기 때문에 좋습니다(자동 생성된 코드는 이를 수행하지 않음).
스타일 설명:
위의 루프는 나중에 반복할 수 있도록 긴 옵션을 짧은 옵션으로 변환해야 합니다
getopts
. 그래서 실제로 작업이 중단됩니다.성능-?
및 와 같은 일부 옵션--help
. IMHO는-h
(또는 적절한 짧은 옵션) 로 번역되어야 합니다 .긴 옵션도 번역할 수 있습니다옵션을 받아들여서는 안되는 지점을 초과했습니다.. 호출 스크립트는 다음과 같습니다.
./script.sh --my-long-flag -- -?
~해야 한다("옵션은 여기서 끝납니다"라는 뜻)은
-?
옵션으로 해석되지 않기 때문입니다.--
비슷하게,./script.sh filename --my-long-flag
~해야 한다
--my-long-option
옵션 구문 분석은 첫 번째 비옵션에서 중지되어야 하므로 옵션으로 해석되지 않습니다 .
위의 사항을 고려한 변형은 다음과 같습니다.
#!/bin/sh
parse=YES
for arg do
shift
if [ "$parse" = YES ]; then
case "$arg" in
--my-long-flag)
set -- "$@" -m ;;
--another-flag)
set -- "$@" -a ;;
--help)
set -- "$@" -h ;;
--)
parse=NO
set -- "$@" -- ;;
--*)
printf 'Unrecognised long option: %s\n' "$arg" >$2
usage
exit 1 ;;
*)
parse=NO
set -- "$@" "$arg"
esac
else
set -- "$@" "$arg"
fi
done
이것은 무엇을 위한 것인가?아니요긴 옵션 허용분리--option hello
( hello
옵션이 아닌 것으로 처리되어 옵션 구문 분석이 종료됩니다) 와 같은 옵션 인수입니다 . --option=hello
그러나 몇 가지 추가 수정을 통해 이와 같은 작업을 쉽게 처리할 수 있습니다.