다음 인수까지 명령줄 인수 옵션을 반복합니다.

다음 인수까지 명령줄 인수 옵션을 반복합니다.

제가 작업 중인 스크립트에 새로 추가된 내용에서는 zsh가 명령의 다음 플래그에 도달할 때까지 플래그와 관련된 매개변수를 반복하고 싶습니다. 예를 들어, 사용자가 다음을 입력하는 경우:

datt -p Package1 Package2 Package3 --build

스크립트는 Package1, Package2Package3각각을 배열의 위치에 할당해야 합니다. 내 사고 과정은 다음과 같습니다.

packages=()
for i in "$@"; do
     packages+=("$i")
done

그래서 제 질문은 명령줄의 다음 플래그가 나타날 때까지 이 루프를 계속 진행하는 스크립트를 어떻게 작성합니까? 질문 시작 부분에 표시된 명령( )을 사용하여 datt -p Package1 Package2 Package3 --buildfor 루프가 --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 )

관련 정보