다음 코드를 보여주는 지침을 따랐습니다.
function testit()
{
local newarray
newarray=($(echo $@))
echo "The new array value is: ${newarray[*]}"
}
myarray=(1 2 3 4 5)
echo "The original array is ${myarray[*]}"
testit ${myarray[*]}
newarray=$(echo $@)
지시문의 또 다른 예가 궁금합니다.arg1=$(echo ${myarray[*]})
newarray=$@
간단하고 직관적이며, 조금 더 노력하면 어떤 이점이 있습니까?
답변1
다음 중 어느 것도 제대로 작동하지 않습니다.
a=($(echo $@))
b=$@
먼저 확장$@
그리고단어 분리기와 와일드카드를 사용하므로 공백이 포함된 값은 그대로 유지되지 않고 와일드카드처럼 보이는 모든 항목이 확장됩니다.
IFS
두 번째는 공백(Bash/ksh) 또는 (Busybox/dash/Zsh; 및 ) "$*"
의 첫 번째 문자와 연결된 배열 요소를 사용하여 전체 배열을 단일 스칼라 값으로 축소합니다.
개념적으로 $@
스칼라 컨텍스트에서 사용하는 것도 잘못된 것 같습니다. 값 목록으로 확장하는 데 사용되지만 여기서는 값 목록을 가질 수 없습니다. 배열 요소를 정말로 연결하고 싶다면 s="$*"
명시적으로 사용하는 것이 좋습니다. (따옴표는 일부 셸에서 오류를 방지하는 데 도움이 됩니다.)
예를 들어:
$ touch file1 file2
$ set -- "foo bar" "*"
$ a=($(echo $@))
$ declare -p a
declare -a a=([0]="foo" [1]="bar" [2]="file1" [3]="file2")
그리고
$ b=$@
$ declare -p b
declare -- b="foo bar *"
$@
배열의 복사본을 만드는 더 좋은 방법은 다음과 같습니다.
c=("$@")
c=("${myarray[@]}")
두 가지 모두 배열 인덱스를 0에서 시작하도록 축소하지만( *
앞과 뒤의 인덱스에 유의하세요):
$ unset l; l[0]="foo bar"; l[2]="*"
$ c=("${l[@]}")
$ declare -p c
declare -a c=([0]="foo bar" [1]="*")
그러나 이것은 일반적으로 문제가 되지 않습니다. 왜냐하면 실수로 연속되지 않은 인덱스가 있는 배열을 얻는 일이 없기 때문입니다.
답변2
newarray=$@
전체 문자열은 배열이 아닌 $@
단일 스칼라 변수에 할당됩니다 .newarray
"명령 대체"를 사용하는 것도 echo
의미가 없습니다. newarray=($@)
배열의 요소 수를 출력할 때 볼 수 있듯이 배열을 성공적으로 할당합니다.
newarray=($@); echo "The new array value is: ${newarray[*]}, ${#newarray[@]}"
The new array value is: 1 2 3 4 5, 5
상대적인
newarray=$@; echo "The new array value is: ${newarray[*]}, ${#newarray[@]}"
The new array value is: 1 2 3 4 5, 1