내 스크립트는 원하는 수의 매개변수와 여러 옵션을 허용합니다.
모든 옵션과 첫 번째 매개변수를 문자열로 추출하고 나머지 매개변수를 두 번째 문자열로 추출해야 합니다. 즉:
./script.sh foo FILE1 [s1="foo" s2="FILE1]"
./script.sh foo FILE1 FILE2 FILE3 [s1="foo" s2="FILE1 FILE2 FILE3]"
./script.sh -i -l foo FILE1 [s1="-i -l foo" s2="FILE1]"
./script.sh -i -l foo FILE1 FILE2 FILE3 [s1="-i -l foo" s2="FILE1 FILE2 FILE3]"
$@
이 두 문자열로 분할하면 됩니다 . 매개변수를 다룰 필요가 없습니다 getopt
. 즉, .
이를 수행하는 가장 쉬운 방법은 무엇입니까?
편집하다:문자열 대신 배열의 배열로 추출하면 트릭이 수행됩니다.
답변1
set -o extendedglob
first_set=("$@[1,(i)^-*]")
first=${(j[ ])first_set}
$first
공백 문자로 시작하지 않고 첫 번째 인수까지 모든 인수를 연결하여 저장됩니다 .-
그런 다음 $second
나머지를 얻을 수 있습니다.
second_set=("$@[$#first_set + 1, -1]")
second=${(j[ ])second_set}
아무튼 이건 $@
아니니 참고하세요끈, 이는 0개 이상의 문자열 목록입니다.
예를 들어 명령줄을 사용하여 Bourne과 유사한 셸에서 스크립트를 호출하는 경우 다음과 같습니다.
script.sh -i -l 'foo bar' 'File 1' File\ 2 "File 3"
그러면 스크립트가 실행됩니다.
execve("/path/to/script.sh", ["script.sh", "-i", "-l", "foo bar",
"File 1", "File 2", "File 3"], environ)
(스크립트가 로 시작한다고 가정 #! /bin/zsh -
):
execve("/bin/zsh", ["/bin/zsh" /* or "script.sh" depending on the system*/,
"-", "/path/to/script.sh", "-i", "-l", "foo bar",
"File 1", "File 2", "File 3"], environ)
스크립트에서 이러한 모든 문자열은 $@
다음 매개변수 argv[]
에 포함됩니다 .execve()
/path/to/script.sh
위에서는 목록을 두 부분으로 나눴습니다.세트( $first_set
및 $second_set
배열 변수), 그런 다음 이 세트의 매개변수를 두 개의 스칼라 변수( $first
및 $second
)로 연결합니다. 그러나 연결이 완료되면 더 이상 원래 매개변수 목록으로 돌아갈 수 없습니다. 예를 들어 $second
이 경우에는 include 가 되며 File 1 File 2 File 3
어떤 공백 문자가 인수를 구분하는 문자인지, 어느 문자가 인수의 일부인지 구별할 수 있는 방법이 없습니다.