Bash 완성의 맥락에서 $ {array [*]}와 $ {array [@]}에 대한 혼동
나는 처음으로 Bash 완성을 작성하는 데 찌르고 많이 Bash 배열 ( ${array[@]}
및 ${array[*]}
) 을 역 참조하는 두 가지 방법에 약간 혼란 스럽습니다 .
다음은 관련 코드 덩어리입니다 (그런데 작동하지만 더 잘 이해하고 싶습니다).
_switch()
{
local cur perls
local ROOT=${PERLBREW_ROOT:-$HOME/perl5/perlbrew}
COMPREPLY=()
cur=${COMP_WORDS[COMP_CWORD]}
perls=($ROOT/perls/perl-*)
# remove all but the final part of the name
perls=(${perls[*]##*/})
COMPREPLY=( $( compgen -W "${perls[*]} /usr/bin/perl" -- ${cur} ) )
}
배열의 모든 요소는 $ {name [subscript]}를 사용하여 참조 할 수 있습니다. 셸의 파일 이름 확장 연산자와의 충돌을 방지하기 위해 중괄호가 필요합니다. 아래 첨자가 '@'또는 '*'이면 단어는 배열 이름의 모든 멤버로 확장됩니다. 이 아래에 첨자는 단어가 큰 따옴표로 묶인 경우에만. 단어가 큰 따옴표 인 경우 $ {name [*]}은 각 배열 구성원의 값이 IFS 변수의 첫 번째 문자로 구분 된 단일 단어로 확장되고 $ {name [@]}은 이름의 각 요소를 확장합니다. 별도의 단어로.
이제 compgen -W
가능한 대안의 단어 목록이 포함 된 문자열 이 예상 된다는 것을 이해한다고 생각 합니다. "$ {name [@]}이 이름의 각 요소를 별도의 단어로 확장합니다"가 의미하는 바를 이해하지 못합니다.
짧은 이야기 : ${array[*]}
작품; ${array[@]}
하지 않습니다. 그 이유를 알고 싶습니다 ${array[@]}
. 정확히 무엇이 확장 되고 더 잘 이해하고 싶습니다 .
(이 Kaleb 페더슨의 대답에 내 의견의 확장이다-의보다 일반적인 치료를 위해 그 답을 [@]
대 [*]
.)
bash (혹은 척 셸)가 명령 줄을 구문 분석 할 때 혼동의 "단어"(나중에 혼동을 피하기 "셸 단어"부름)로 분할합니다. 일반적으로 쉘 단어는 공백 (또는 기타 공백)으로 공백은 이스케이프 또는 인용을 통해 쉘 단어에 사용할 수 있습니다. 큰 따옴표로 묶인 배열 [@]
과 [*]
확장 배열 의 차이점은 배열의 각 "${myarray[@]}"
요소가 별도의 셸 단어로 처리되는 반면 "${myarray[*]}"
배열의 셸 단어 가 공백으로 구분 된 셸 단어가됩니다 (또는의 첫 문자가 무엇이든 IFS
).
일반적으로 [@]
행동은 당신이 원하는 것입니다. 우리가 가지고 있고 perls=(perl-one perl-two)
사용 하는 가정 ls "${perls[*]}"
합니다 ls "perl-one perl-two"
. 이것은 단일 파일을 단일 파일을 perl-one perl-two
것입니다. ls "${perls[@]}"
상당이다 ls "perl-one" "perl-two"
훨씬 더 가능성이있는 일을 할 것입니다.
완성 된 단어 목록 (셸 단어와의 혼동을 피하기 위해 comp-words라고 부름)을 제공하는 compgen
것입니다. 이 -W
옵션은 comp-word 목록을 가져 오기 오지만, comp-word가 공백으로 구분 된 단일 쉘-워드 형식이어야합니다. 항상 (적어도 내가 아는 한) 인수를받는 명령 옵션은 단일 쉘 단어를 사용합니다. 정렬 옵션에 대한 인수가 언제 끝나는 지 알 수있는 방법이 일반 명령 인수 (/ other 옵션 플래그) 시작합니다.
더 자세하게 :
perls=(perl-one perl-two)
compgen -W "${perls[*]} /usr/bin/perl" -- ${cur}
다음과 달라집니다.
compgen -W "perl-one perl-two /usr/bin/perl" -- ${cur}
... 당신이 원하는 것을. 반면에
perls=(perl-one perl-two)
compgen -W "${perls[@]} /usr/bin/perl" -- ${cur}
다음과 달라집니다.
compgen -W "perl-one" "perl-two /usr/bin/perl" -- ${cur}
... 완전한 말도 안되는 말입니다. "perl-one"은 -W 플래그에 첨부 된 유일한 comp-word이고, compgen이 완성 될 것입니다. 첫 번째 실제는 "perl-two"입니다. / usr / bin / perl "입니다. 나는 compgen이 추가 인수 ("- "및 $ cur에있는 모든 것)가 주어 졌다고 불평 할 것으로 예상하지만 무시합니다.
은 제목 ${array[@]}
-to- 에 대해 ${array[*]}
묻지 만 어느 $array[*]
-to- 에 대해 물어 보는 $array[@]
것이 약간 혼란 스럽습니다. 나는 둘 다 대답 할 것이다 :
배열 변수를 인용 @
하고 아래에 첨자로 사용하면 배열의 $IFS
각 요소는 해당 콘텐츠 확장 서열 수있는 공백 (실제로는 하나 )에 관계없이 전체 콘텐츠로 됩니다. 별표 ( *
)를 아래 첨자로 사용하면 ( 인용 여부에 관계없이)에서 각 배열 요소의 콘텐츠를 분할하여 새 콘텐츠로 확장 할 수 있습니다 $IFS
.
다음은 예제 펼쳐입니다.
#!/bin/sh
myarray[0]="one"
myarray[1]="two"
myarray[3]="three four"
echo "with quotes around myarray[*]"
for x in "${myarray[*]}"; do
echo "ARG[*]: '$x'"
done
echo "with quotes around myarray[@]"
for x in "${myarray[@]}"; do
echo "ARG[@]: '$x'"
done
echo "without quotes around myarray[*]"
for x in ${myarray[*]}; do
echo "ARG[*]: '$x'"
done
echo "without quotes around myarray[@]"
for x in ${myarray[@]}; do
echo "ARG[@]: '$x'"
done
다음은 출력입니다.
with quotes around myarray[*]
ARG[*]: 'one two three four'
with quotes around myarray[@]
ARG[@]: 'one'
ARG[@]: 'two'
ARG[@]: 'three four'
without quotes around myarray[*]
ARG[*]: 'one'
ARG[*]: 'two'
ARG[*]: 'three'
ARG[*]: 'four'
without quotes around myarray[@]
ARG[@]: 'one'
ARG[@]: 'two'
ARG[@]: 'three'
ARG[@]: 'four'
나는 개인적으로 보통 원한다 "${myarray[@]}"
. 이제, 질문의 두 번째 부분에 대답 ${array[@]}
대 $array[@]
.
인용 한 bash 문서를 인용합니다.
셸의 파일 이름 확장 연산자와의 충돌을 방지하기 위해 중괄호가 필요합니다.
$ myarray=
$ myarray[0]="one"
$ myarray[1]="two"
$ echo ${myarray[@]}
one two
그러나 그렇게 할 때 $myarray[@]
달러 기호는 단단히 묶여 myarray
있으므로 [@]
. 예를 들면 :
$ ls $myarray[@]
ls: cannot access one[@]: No such file or directory
그러나 문서에서 언급했듯이 대괄호는 파일 이름 확장을위한 것이므로 다음을 시도해보십시오.
$ touch one@
$ ls $myarray[@]
one@
이제 확장 후 파일 이름 확장이 발생했음을 알 수 있습니다 $myarray
.
그리고 $myarray
아래 첨자가없는 또 하나의 메모 는 배열의 첫 번째 값으로 확장됩니다.
$ myarray[0]="one four"
$ echo $myarray[5]
one four[5]
'ProgramingTip' 카테고리의 다른 글
생성시 "ID 필드가 필요합니다"유효성 검사 메시지; (0) | 2020.11.04 |
---|---|
jquery Enter 키를 활성화하고 이벤트를 탭으로 변경하는 방법 (0) | 2020.11.04 |
MVC 반환 부분보기를 JSON으로 (0) | 2020.11.04 |
C # .NET을 사용하여 폴더에 "Everyone"권한 추가 (0) | 2020.11.04 |
Putty (ssh)를 사용하여 서버에 파일을 업로드하는 방법 (0) | 2020.11.04 |