sourcecode

배시 완료와 관련하여 ${array[*]} 대 ${array[@]}에 대한 혼동

codebag 2023. 5. 8. 22:12
반응형

배시 완료와 관련하여 ${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} ) )
}

bash의 문서에는 다음과 같이 나와 있습니다.

어레이의 모든 요소는 ${name[subscript]}을(를) 사용하여 참조할 수 있습니다.셸의 파일 이름 확장 연산자와 충돌하지 않으려면 중괄호가 필요합니다.첨자가 '@' 또는 '*'이면 단어가 배열 이름의 모든 구성원으로 확장됩니다.이러한 첨자는 단어가 큰따옴표 안에 나타날 때만 다릅니다.단어가 이중 따옴표로 묶이면 ${name[*]}은(는) IFS 변수의 첫 번째 문자로 구분된 각 어레이 멤버 값을 가진 단일 단어로 확장되고 ${name[@]}은(는) 이름의 각 요소를 별도 단어로 확장합니다.

이제 이해할 수 있을 것 같아요.compgen -W에서는 가능한 대체 단어 목록이 포함된 문자열을 예상하지만, 이 맥락에서 "${name[@]}이(가) 이름의 각 요소를 별도의 단어로 확장"한다는 의미가 무엇인지 이해할 수 없습니다.

긴 이야기 요약:${array[*]}작업;${array[@]}Doesn't.그 이유를 알고 싶고, 정확히 무엇인지 더 잘 이해하고 싶습니다.${array[@]}으로 확장됩니다.

(이것은 케일럽 페더슨의 대답에 대한 제 의견의 확장입니다. 더 일반적인 치료를 위한 대답을 보십시오.[@][*].)

bash(또는 유사한 셸)가 명령줄을 구문 분석할 때 일련의 "단어"(나중에 혼동을 피하기 위해 "shell-words"라고 부르겠습니다)로 분할됩니다.일반적으로 셸 워드는 공백(또는 다른 공백)으로 구분되지만 공백은 이스케이프 또는 따옴표를 사용하여 셸 워드에 포함될 수 있습니다.사이의 차이[@]그리고.[*]- 어레이를 이중 패리티로 연결하면 다음과 같은 효과를 얻을 수 있습니다."${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"유용한 일을 할 가능성이 훨씬 더 높습니다.

단어 을 제공하는 은 ( 콤프 입니다) 셸 단 목 것 는 하 공 제 록 어 혼 피 기 위 완 단 콤 해 프 고 것 를 드 부 라 워 료 하 어 와 동 을 의 을 셸compgen 다니다릅.-W옵션은 콤팩트 워드 목록을 사용하지만 콤팩트 워드가 공백으로 구분된 단일 셸 워드 형식이어야 합니다.인수를 사용하는 명령 옵션은 항상 단일 셸 워드를 사용합니다. 그렇지 않으면 옵션 인수가 언제 종료되고 일반 명령 인수(/기타 옵션 플래그)가 시작되는지 알 수 없습니다.

자세한 내용:

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 플래그에 연결된 유일한 컴프워드이며, compgen이 완료할 문자열로 취할 첫 번째 실제 인수는 "perl-two /usr/bin/perl"입니다.저는 컴겐이 추가 인수("--" 및 $cur로 표시된 것)가 주어졌다고 불평할 것으로 예상하지만, 분명히 그것은 그것들을 무시합니다.

당신의 제목은 다음과 같습니다.${array[@]}${array[*]}(둘 다 (둘다내에서)▁() 내에서{}하지만 당신은 다음에 대해 묻습니다.$array[*]$array[@](둘 다 (둘다없음)) 없이{} 좀요. 약간 혼란스럽습니다.{}):

을 합니다.@각첨, 자, 배열각예, 공관전내이확로체장니다용됩하으나계중없서에백요는, 소다음의로예▁as▁regard▁(,▁of▁of▁subscript▁each▁is: ,▁oneactually중하나음다▁to▁a▁expanded▁arraypace▁content▁its(다▁element$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[@]}"두이제질, 두의문번부째분답위해하기에의당신▁the,▁of위해▁now▁answer,▁second,${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팽창

한 더, 그고한가더지리,,더▁and,$myarray첨자를 지정하지 않으면 배열의 첫 번째 값으로 확장됩니다.

$ myarray[0]="one four"
$ echo $myarray[5]
one four[5]

언급URL : https://stackoverflow.com/questions/3348443/a-confusion-about-array-versus-array-in-the-context-of-a-bash-comple

반응형