![다음 인수까지 명령줄 인수 옵션을 반복합니다.](https://linux55.com/image/195692/%EB%8B%A4%EC%9D%8C%20%EC%9D%B8%EC%88%98%EA%B9%8C%EC%A7%80%20%EB%AA%85%EB%A0%B9%EC%A4%84%20%EC%9D%B8%EC%88%98%20%EC%98%B5%EC%85%98%EC%9D%84%20%EB%B0%98%EB%B3%B5%ED%95%A9%EB%8B%88%EB%8B%A4..png)
제가 작업 중인 스크립트에 새로 추가된 내용에서는 zsh가 명령의 다음 플래그에 도달할 때까지 플래그와 관련된 매개변수를 반복하고 싶습니다. 예를 들어, 사용자가 다음을 입력하는 경우:
datt -p Package1 Package2 Package3 --build
스크립트는 Package1
, Package2
및 Package3
각각을 배열의 위치에 할당해야 합니다. 내 사고 과정은 다음과 같습니다.
packages=()
for i in "$@"; do
packages+=("$i")
done
그래서 제 질문은 명령줄의 다음 플래그가 나타날 때까지 이 루프를 계속 진행하는 스크립트를 어떻게 작성합니까? 질문 시작 부분에 표시된 명령( )을 사용하여 datt -p Package1 Package2 Package3 --build
for 루프가 --build
패키지 이름을 캡처하는 것을 방지하고 배열에 문자열 추가를 중지하도록 하려면 어떻게 해야 합니까 PackageN
?
답변1
매개변수를 올바르게 구문 분석하는 것은 성가실 수 있습니다. 나는 당신이 사용하는 것이 좋습니다선택받기(1). 여기에서 동일한 플래그를 여러 번 지정할 수 있습니다.
datt -p Package1 -p Package2 -p Package3 --build
어떤 이유로 플래그를 재사용할 수 없는 경우(무엇인지는 확실하지 않지만...) 매개변수를 개별 항목으로 전달하고 공백을 구분할 수도 있습니다.
datt -p "Package1 Package2 Package3" --build
답변2
shift
이 구문 분석을 수행하려면 배열이 비어 있을 때까지 while 루프를 사용하는 것이 더 쉽습니다 .
packages=()
while (($#)); do
case $1 in
-p)
while shift; [[ $1 != -* ]]; do
packages+=($1)
done
…
esac
shift
done
당신은 그것을 사용할 수 있습니다i
아래 첨자 기호내부 루프를 실행하여 다음 옵션을 찾으세요. $array[(i)PATTERN]
는 첫 번째로 일치하는 요소의 인덱스입니다 PATTERN
. 인덱스는 1부터 시작하므로 1을 빼서 나머지 요소 수를 구합니다. 일치하는 항목이 없으면 PATTERN
값은 마지막 요소의 인덱스에 1을 더한 값이므로 이 경우에도 이와 같은 코드가 작동합니다.
packages=()
while (($#)); do
case $1 in
-p) ((n = $@[(i)-*] - 1)); packages+=($@[1,$n]); shift $n;;
…
esac
shift
done
설명하는 구문은 비표준입니다. 이러한 이유로 나는 이 작업을 수행하지 않는 것이 좋습니다. 사용자에게 혼란을 줄 수 있기 때문입니다. 보통 datt -p Package1 Package2 Package3 --build
같은 일을 합니다 datt -p Package1 Package2 --build Package3
.
답변3
일반적으로 가장 현명한 방법은 루프의 모든 옵션을 살펴보고 콘텐츠를 올바른 위치에 배치하는 것입니다. 일반적으로 매개변수 구문 분석 루프에서 처리하지 않지만 옵션의 순서가 중요하다면 의미가 있을 수 있습니다.
예를 들어 다음과 같은 루프(Bash 또는 zsh의 경우)는 다음과 같습니다.
#!/usr/bin/zsh
packages=()
while [ "$#" -gt 0 ]; do
case $1 in
-p) echo "p option seen...";;
--build) echo "--build option seen after ${#packages[@]} packages...";;
*) echo "adding package '$1'";
packages+=("$1");;
esac
shift;
done
typeset -p packages;
줄게:
$ zsh dattest.sh -p foo bar doo --build
p option seen...
adding package 'foo'
adding package 'bar'
adding package 'doo'
--build option seen after 3 packages...
typeset -a packages=( foo bar doo )