Ich versuche zum ersten Mal, eine Bash-Vervollständigung zu schreiben, und bin etwas verwirrt über die beiden Möglichkeiten, Bash-Arrays ( ${array[@]}
und ${array[*]}
) zu dereferenzieren .
Hier ist der relevante Codeabschnitt (er funktioniert übrigens, aber ich würde ihn gerne besser verstehen):
_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} ) )
}
In der Dokumentation von bash heißt es :
Auf jedes Element eines Arrays kann mit $ {name [tiefgestellt]} verwiesen werden. Die geschweiften Klammern sind erforderlich, um Konflikte mit den Dateinamenerweiterungsoperatoren der Shell zu vermeiden. Wenn der Index '@' oder '*' ist, wird das Wort auf alle Mitglieder des Array-Namens erweitert. Diese Indizes unterscheiden sich nur, wenn das Wort in doppelten Anführungszeichen steht. Wenn das Wort in doppelte Anführungszeichen gesetzt ist, wird $ {name [*]} zu einem einzelnen Wort erweitert, wobei der Wert jedes Array-Mitglieds durch das erste Zeichen der IFS-Variablen getrennt wird, und $ {name [@]} erweitert jedes Element des Namens zu einem separaten Wort.
Jetzt denke ich, dass ich verstehe, compgen -W
dass eine Zeichenfolge erwartet wird, die eine Wortliste möglicher Alternativen enthält, aber in diesem Zusammenhang verstehe ich nicht, was "$ {name [@]} jedes Element des Namens zu einem separaten Wort erweitert" bedeutet.
Lange Rede, kurzer Sinn: ${array[*]}
Werke; ${array[@]}
nicht. Ich würde gerne wissen warum und ich würde gerne besser verstehen, worauf es genau ${array[@]}
ankommt.
quelle
Ihr Titel fragt nach
${array[@]}
Versus,${array[*]}
aber dann fragen Sie nach$array[*]
Versus,$array[@]
was etwas verwirrend ist. Ich werde beide beantworten:Wenn Sie eine Array-Variable zitieren und
@
als Index verwenden, wird jedes Element des Arrays auf seinen vollständigen Inhalt erweitert, unabhängig von Leerzeichen (tatsächlich eines von$IFS
), die in diesem Inhalt vorhanden sein können. Wenn Sie das Sternchen (*
) als Index verwenden (unabhängig davon, ob es in Anführungszeichen steht oder nicht), wird es möglicherweise auf neuen Inhalt erweitert, der durch Aufteilen des Inhalts jedes Array-Elements bei erstellt wird$IFS
.Hier ist das Beispielskript:
Und hier ist die Ausgabe:
Ich persönlich möchte normalerweise
"${myarray[@]}"
. Nun, zu beantworten , den zweiten Teil Ihrer Frage,${array[@]}
gegenüber$array[@]
.Zitieren der Bash-Dokumente, die Sie zitiert haben:
Wenn Sie dies jedoch tun
$myarray[@]
, ist das Dollarzeichen eng an das Dollarzeichen gebunden,myarray
sodass es vor dem ausgewertet wird[@]
. Beispielsweise:Wie in der Dokumentation angegeben, dienen die Klammern jedoch zur Erweiterung des Dateinamens. Versuchen wir also Folgendes:
Jetzt können wir sehen, dass die Dateinamenerweiterung nach der Erweiterung stattgefunden
$myarray
hat.Und noch eine Anmerkung
$myarray
ohne Index wird auf den ersten Wert des Arrays erweitert:quelle
IFS
wirkt sich unterschiedlich auf die Ausgabe in Abhängigkeit@
gegenüber*
und gegenüber nicht notierte zitiert.${array[*]}
oder${array[@]}
. Das Fehlen von Zahnspangen war einfach Nachlässigkeit. Können Sie darüber hinaus erklären, worauf${array[*]}
sich dercompgen
Befehl auswirken würde ? Was bedeutet es in diesem Zusammenhang, das Array in jedes seiner Elemente separat zu erweitern?${array[@]}
normalerweise der richtige Weg ist. Ich versuche zu verstehen, warum in diesem Fall nur${array[*]}
funktioniert.