#!/bin/bash
if [ $# -gt 0 ]; then
snum=( $@ )
echo $snum
fi
./testscript.sh 1234 4568
The Output of echo command is only 와 같은 스크립트를 실행할 때 1234
모든 위치 매개변수의 배열을 구축하지 않는 것 같나요?
#!/bin/bash
if [ $# -gt 0 ]; then
snum="$@"
echo $snum
fi
./testscript.sh 1234 4568
출력을 실행하면 다음과 같습니다.1234 4568
snum=( $@ )
왜 첫 번째 위치 매개변수만 사용되는지 궁금합니다 .
답변1
목록 컨텍스트 "$@"
(큰따옴표 포함)에서 사용하여 가져옵니다.목록개별적으로 인용된 위치 매개변수입니다.
스칼라 컨텍스트 "$*"
(큰따옴표 포함)에서 사용하여 위치 인수를 연결합니다.단일 문자열첫 번째 문자 $IFS
(일반적으로 공백)를 구분 기호로 사용합니다.
$@
따옴표 없이(첫 번째 예에서처럼) 또는 "$@"
스칼라 컨텍스트에서(두 번째 예에서처럼) 사용하는 것은 거의 의미가 없습니다. bash
셸 에서 스칼라 컨텍스트에서 사용하는 "$@"
것은 첫 번째 문자를 공백으로 설정하는 것과 같습니다."$*"
$IFS
사용하면 snum=( "$@" )
배열이 생성됩니다 snum
. 변수에 로 접근하면 $snum
배열의 첫 번째 요소를 얻게 됩니다. 실제로는 access 와 동일합니다 ${snum[0]}
. "${snum[@]}"
유사한 방식으로 개별적으로 참조되는 요소를 제공하는 목록을 사용하십시오 "$@"
. 를 사용하면 "${snum[*]}"
동등한 결과를 얻을 수 있지만 "$*"
배열의 경우입니다 snum
.
snum
위치 인수 목록에서 배열을 생성한 다음 비어 있지 않은 경우 해당 배열을 인쇄 한다고 가정하면 다음을 사용할 수 있습니다.
#!/bin/bash
snum=( "$@" )
if [ "${#snum[@]}" -gt 0 ]; then
printf '%s\n' "${snum[@]}"
fi
snum
스크립트에 인수가 제공되면 요소가 별도의 줄에 인쇄됩니다.
실행 예시:
bash-5.1$ ./script 1 2 3 "hello world" 4
1
2
3
hello world
4
이 hello world
매개변수는 단일 매개변수로 유지됩니다.아니요주변 따옴표를 잊어버리면 이런 일이 발생합니다 $@
.
콜론으로 구분된 단일 문자열의 위치 인수 목록을 인쇄합니다. 문자열을 수정하여 위치 매개변수 사이에 콜론을 삽입합니다 $IFS
.
#!/bin/bash
IFS=:
snum="$*"
if [ -n "$snum" ]; then
printf '%s\n' "$snum"
fi
차이점은 snum
이제 요소 배열이 아닌 단일 문자열이라는 점입니다. 문자열이 비어 있지 않은 경우, 즉 비어 있지 않은 인수가 하나 이상 스크립트에 제공된 경우 스크립트는 문자열을 출력합니다.
snum
또는 계속해서 배열 로 사용되도록 첫 번째 예제를 약간 수정하여 ,
#!/bin/bash
snum=( "$@" )
if [ "${#snum[@]}" -gt 0 ]; then
IFS=:
printf '%s\n' "${snum[*]}"
fi
실행 예시:
bash-5.1$ ./script 1 2 3 "hello world" 4
1:2:3:hello world:4
답변2
var=( values )
배열 변수 할당입니다
var=value
는 스칼라 변수 할당입니다(그리고 var="$@"
에는 var
아래와 같이 위치 인수와 공백을 연결하여 할당됩니다).하나스칼라이기 때문에 문자열입니다)
$var
배열의 요소는 인덱스 0의 요소로 확장됩니다. 이는 ${var[0]}
배열의 모든 요소에 필요한 것과 동일하며 ${var[@]}
Korn 셸에서 복사한 잘못된 디자인입니다.
또한 참고하십시오:
- Split+glob 연산자는 목록 컨텍스트에서 인용되지 않은 인수 확장을 유지하는데, 이는 거의 원하지 않습니다. 아이러니하게도 위에서 인용문을 추가하는 유일한 곳은 인용문이 필요하지 않은 곳뿐입니다.
echo
출력의 임의 데이터에는 사용할 수 없습니다bash
.
원하는 곳은 다음과 같습니다.
#! /bin/bash -
print_space_separated() {
local IFS=' '
printf '%s\n' "$*"
}
if [ "$#" -gt 0 ]; then
snum=( "$@" )
print_space_separated "${snum[@]}"
fi
zsh
who 의 배열 설계가 의 배열 설계 보다 가까운 경우 다음을 수행할 수 있습니다.csh
ksh
#! /bin/zsh -
if (( $# > 0 )) {
snum=( $argv )
print -r -- $snum
}
(그 print -r
자체는 ksh에서 유래)
그러나 따옴표 없이 배열 확장을 두면 이 셸에서 인수 확장이 발생할 때 분할+glob 없이도 빈 요소가 계속 제거됩니다. 이를 보존하려면 ksh 구문이 필요합니다.
#! /bin/zsh -
if (( $# > 0 )) {
snum=( "$@" )
print -r -- "${snum[@]}"
}
( "${snum[@]}"
'로 단축할 수도 있지만 "$snum[@]"
).
in var="$@"
또는 에는 var="${array[@]}"
in 의 첫 번째 문자 와 공백으로 연결된 var
위치 인수로 구성된 문자열이 포함됩니다 . POSIX 지정되지 않은 동작은 참조 및 목록 컨텍스트에서만 사용됩니다. 이식성의 첫 번째 문자와 연결된 위치 인수를 얻으려면 (목록 또는 비목록 컨텍스트에서)를 사용하세요.$IFS
zsh
bash
$@
$IFS
"$*"
배열 요소를 임의의 문자열( 의 첫 번째 문자 제외)과 연결하려면 $IFS
: 에서 j
매개변수 확장 플래그를 사용하세요. 이에 상응하는 것은 없습니다. 가지다.zsh
${(j[that-string])array}
bash
fish
string join -- that-string $array