매개변수 분석을 공부할 때세게 때리다스크립트 사용법선택 항목 가져오기, 나는 거의 모든 곳에서 이 구조가 사용되는 것을 보았습니다: eval set -- "$SOMETHING_PARSED"
. 예를 들어,여기그리고여기. 앞으로는 작업 스크립트를 무료로 공개할 예정이므로 사용자들에게 그런 공백을 남기고 싶지 않습니다. 이것을 피할 수 있는 방법이 있나요?
설명하다여기버전에 따라 다릅니다선택 항목 가져오기, 사용할 필요가 없습니다 eval
. 하지만 적어도 내 경우는 그렇지 않다.선택 항목 가져오기다음과 같은 문자열이 주어지면 ' -j --version= '\''1'\'' --number= '\''2'\'' -- '\''2C_IA/GBCs_out/nohope_2C_IA_off. xml'\'''
.& set
는 이를 정확히 에 할당합니다 $1
.
답변1
getopt
비전통적인 방식으로 구현되거나 util-linux
적어도 비전통적인 방식으로 사용되는 전체 요점 busybox
은 평가할 쉘 코드를 출력한다는 것입니다. 쉘 구문의 특수 문자는 실제로 옵션 인수 1에서 인용되므로 getopt
²를 제외하고 Bourne과 유사한 쉘에서 사용해도 안전합니다.yash
POSIX sh
언어를 사용하면 명령이 임의의 문자열 목록을 셸에 반환하는 가장 간단한 방법입니다.
getopt
이 작업 모드를 지원하지 않는 구현(예: getopt
분할+글로브 연산자 사용에 의존한 원래 구현)은 임의 목록을 반환할 수 없기 때문에 의도적으로 손상되었습니다.
eval
어떤 이유로든 사용하고 싶지 않지만 zsh
전환할 수 있는 옵션이 있는 경우 다음을 사용할 수 있습니다.
argv=( "${(@XQ)${(z)$(getopt...)}}" ) || exit
매개 변수 확장 플래그는 쉘 인용 구문( 인용 구문이지만 작은 따옴표만 사용하여 인용) z
을 기반으로 표시되며 , 따옴표를 제거하고 구문 오류가 발생하면 불평합니다.zsh
getopt
Q
X
유일한 이점은 getopt
사악한 코드를 출력하는 사악한 명령으로 대체되면 실행되지 않는다는 것입니다.사악한 놈교체 중입니다 getopt
. 가져가는 편이 나을 수도 있습니다.달리기평가할 수 있도록 출력하는 것이 아니라 사악한 코드 자체입니다.
NUL로 구분된 명령을 보내는 경우 출력을 배열로 읽어서 임의의 문자열 목록을 bash
4.4+ 에 전달할 수 있습니다.sh
readarray -td '' array < <(cmd) || exit # readarray failed.
wait "$!" || exit # cmd failed
set -- "${array[@]}"
또는 다음과 같습니다 zsh
:
argv=( "${(0@)$(cmd)}" ) || exit
argv[-1]=() # remove the empty trailing argument caused by the terminating NUL
getopt
따라서 이론적으로 이 작동 모드를 사용하여 메서드를 구현하는 것이 가능합니다 .
이 getopt
유틸리티는 출력을 평가할 것으로 예상되는 유일한 유틸리티는 아닙니다. 다음도 참조하세요.
eval "$(dbus-launch --sh-syntax)"
eval "$(dpkg-architecture -u)"
eval "set $(git rev-parse --sq --prefix "$prefix" -- "$@")"
eval "$(lesspipe)"
eval "$(xz --robot --version)"
eval "$(resize)"
eval "$(dircolors)"
쉘의 환경을 수정하는 데 사용됩니다.
현재 상태를 저장하고 나중에 복원하는 데 사용할 수 있는 모든 항목도 참조하세요.
aliases=$(alias -L) # zsh
aliases=$(alias -p) # ksh/bash
options=$(set +o)
locale=$(locale)
되돌리려 면 eval "$aliases"
...eval "$options"
getopt
사용된 구문 분석 옵션을 포함하지 않는 대안은 다음과 같습니다 eval
.
- 표준
getopts
내장 기능(ksh93
³ 제외)은 단일 문자 옵션만 지원합니다. zsh
zparseopts
큐브 의- 내 거
getopts_long
POSIXsh
함수
¹ 옵션 이름에는 없지만 적어도 버전 2.38에서는 버그로 간주될 수 있습니다. 스크립트 옵션에 어리석은 이름을 선택하지 않는 한 괜찮을 것입니다.
² 현재 버전 yash
(2022년 6월 기준)은 유효한 텍스트만 처리할 수 있으므로 현재 로캘에서 텍스트로 디코딩할 수 없는 인수는 차단됩니다.
³ ksh93 getopts
이나 zsh는 zparseopts
GNU(또는)와 같은 방식으로 옵션을 구문 분석하지 않습니다. 특히, 축약된 긴 옵션을 지원하지 않습니다.getopt_long()
util-linux
getopt