긴 옵션("--option")만 지원하려는 bash 스크립트가 있습니다. --옵션에는 선택적으로 하나 이상의 인수가 있을 수 있습니다. 첫 번째 '--' 또는 명령줄 문자열의 끝을 포함하지 않는 모든 단어(공백으로 구분된 모든 단어)는 "--옵션 인수"로 간주됩니다. 결과의 후행 공백은 괜찮습니다. 이 함수는 가능한 각 옵션에 대해 다른 함수에 의해 호출되므로 최대 성능이 요구됩니다. 따라서 bash 루프와 외부 명령을 피하려고 노력합니다.
내가 발견할 때까지 "첫 번째 발생" 문제로 여러 시간 동안 싸웠습니다.이 답변이는 POSIX(및 bash)가 탐욕스럽지 않고 게으른 정규식 연산자를 지원하지 않는다는 것을 상기시켜주었습니다.
무엇을 해야 할까요?
답변1
옵션은 문자열로 전달되지 않고목록문자열의. , , , 및 별도의 인수가 있으며 공백을 포함하는 항목은 없습니다 myscript --option foo bar -- qux
.myscript
--option
foo
bar
--
qux
루프는 bash에 들어가는 방법입니다.
case "$1" in
--option1)
shift
while [[ $# -ne 0 && "$1" != "--" ]]; do
option1_args+=("$1")
shift
done
(($# == 0)) || shift
done
성능이 그렇게 큰 문제라면 bash를 사용해서는 안됩니다. 대신 ksh를 사용해 보세요. 무료이고 기본적으로 설치되지 않더라도 거의 모든 곳에서 사용할 수 있으며 bash보다 훨씬 빠른 경우가 많습니다. 그래도 너무 느리다면 Perl, Python 또는 Ruby와 같은 고급 프로그래밍 언어가 필요합니다.
답변2
이 매우 간단한 해결책을 찾았습니다 ...
function optionArg () {
local _find="$1"; shift 1
local _optarg=""
local _reBeg=""
#
_reBeg="${_find}"'[= ]+(.*?)( --)?'
### no regex nongreedy operator support in POSIX
### will have to just truncate after first match
#
if [[ "$*" =~ $_reBeg ]]
then
_optarg="${BASH_REMATCH[1]}"
### all arguments following --option[= ]
#
_optarg="${_optarg%%--*}"
### limit to just arguments up to next --option (no lazy support in POSIX)
#
return 0
else
return 1
fi
다음과 같은 다른 옵션이 뒤따르는 옵션이 포함된 스크립트 또는 함수 호출이 제공됩니다.
otherfunction --option1 arg1 arg2 --option2 -- file1 /home/me/file2
otherfunction()이 허용하는 각 옵션에 대해 optionArg()는 다음과 같이 호출됩니다.
_optarg1="$(optionArg --option1 "$@")"
_optarg2="$(optionArg --option2 "$@")"
_optarg3="$(optionArg -- "$@")"
결과는 다음과 같습니다...
_optarg1="arg1 arg2 "
_optarg2=""
_optarg3="file1 /home/me/file2"