사용자가 지정한 매개변수를 사용하여 하위 디렉터리에서 화물 명령을 실행합니다.

사용자가 지정한 매개변수를 사용하여 하위 디렉터리에서 화물 명령을 실행합니다.

내 디렉토리 구조는 다음과 같습니다.

rust/
├── dir1/
│   └── Cargo.toml
└── dir2/
    └── Cargo.toml

rust이 디렉토리에서 실행될 zsh 스크립트를 생성하고 Cargo.toml파일이 있는 각 하위 디렉토리 에 대해 cargo사용자가 지정한 매개변수를 사용하여 명령을 실행하고 싶습니다 .

예:

run.sh "test -- --ignored"실행해야 cargo -v test -- --ignored --manifest-path ./dir1/Cargo.toml하며 cargo -v test -- --ignored --manifest-path ./dir2/Cargo.toml.

큰따옴표는 쉘이 혼동되는 것을 방지하는 데 유용합니다 --. 사용자는 큰따옴표 없이 다른 매개변수를 전달할 수 있습니다 --.

이것을 시도했지만 find . -name 'Cargo.toml' -type f -print -exec cargo -v "$@" --manifest-path {} \;"오류: 해당 하위 명령 없음: test --ignored" 오류가 발생했습니다. 분명히 전체 내용은 개별 문자열이 아닌 문자열로 전달됩니다.

어떻게 해야 하나요?

답변1

껍질은 그렇지 않습니다혼란시키다--.

그냥 해:

#! /bin/zsh -
for toml (**/Cargo.toml(N.)) cargo -v "$@" --manifest-path $toml

그리고 그것을 호출하십시오 :

that-script test -- --ignored

zsh globbing을 사용하면 다음과 같은 몇 가지 장점이 있습니다 find.

  • 숨겨진 파일 및 디렉터리는 무시됩니다( D필요하지 않은 경우 한정자를 추가하세요).
  • 목록이 정렬되었습니다.
  • {}포함된 매개변수를 에 전달할 수 있습니다 cargo.

스크립트에 인수를 전달하고 쉘이 이를 공백 문자로 분할하고 결과 단어를 별도의 인수로 전달하도록 하려면 cargo다음을 수행할 수 있습니다.

#! /bin/zsh -
for toml (**/Cargo.toml(N.)) cargo -v ${(s[ ])1} --manifest-path $toml

$1또는 문자별로 분할합니다 (기본값은 공백, 탭 개행 및 nul) .$IFS$=1

그런 다음 다음으로 전화할 수 있습니다.

that-script 'test -- --ignored'

그러나 이는 사용자가 공백(또는 IFS 문자)이 포함된 매개변수를 에 전달할 수 없음을 의미합니다 cargo.

z또는 Z[options]또는 인수 확장 플래그를 사용하여 Q해당 인수 하나를 토큰화하고 인용 제거하도록 셸에 지시할 수 있습니다. "${(Q@)${(Z[n])1}}"( 는 ewline Z[n]n구분 기호로도 허용됩니다 . 주석 z[Cn]식별 및 제거 , 큰따옴표 안에 빈 요소 유지 참조), 루프에서 매번 토큰화를 수행하지 않도록 토큰화를 한 번만 수행하거나 토큰화를 (일명 )에 저장하면 첫 번째로 돌아갈 수 있습니다.C@$argv$@

#! /bin/zsh -
argv=( "${(Q@)${(Z[n])1}}" )
for toml (**/Cargo.toml(N.)) cargo -v "$@" --manifest-path $toml

그런 다음 다음을 수행할 수 있습니다.

that-script "test -- --opt1='foo bar' --opt2=$'blah\nblah' --opt3 ''"

예를 들어 and test, --, --opt1=foo bar및 빈 문자열은 별도의 인수로 전달 --opt2=blah<newline>blah됩니다 .--opt3cargo

그러나 사용자가 모든 매개변수를 스크립트에 개별적으로 전달하도록 할 수 있는 경우(구문은 다음과 같습니다.그들의위의 Z/ 플래그 Q에는 인용 구문이 필요 하지만 zsh위의 첫 번째 예에서와 같이 이를 표준과 함께 전달하는 스크립트가 필요합니다.cargo"$@"


--manifest-path path/to/Cargo.toml이제 문제는 하위 명령의 옵션 구분 기호 앞에 있다는 것이 밝혀졌습니다 . 다음과 같이 언제든지 이러한 매개변수를 사용자 전달 매개변수 목록에 삽입할 수 있습니다.--test

#! /bin/zsh -
for toml (**/Cargo.toml(N.)) (
  argv[2,0]=(--manifest-path $toml)
  cargo -v "$@"
)

이렇게 하면 사용자가 호출할 때 that-script test -- --ignored스크립트가 결국 호출됩니다 cargo -v test --manifest-path path/to/Cargo.toml -- --ignored.

관련 정보