Was ist der Unterschied zwischen $@ und $*

Was ist der Unterschied zwischen $@ und $*

Entsprechenddiese Seite, $@ und $* machen so ziemlich dasselbe:

The $@ holds list of all arguments passed to the script. 
The $* holds list of all arguments passed to the script.

Nachdem ich alle Top-Treffer bei Google durchsucht habe, kann ich keine Erklärung dafür finden, warum es zwei scheinbar doppelte Syntaxen gibt.

Sie scheinen in meinen Skripten gleich zu funktionieren.

cat foo.sh
#!/bin/bash
echo The parameters passed in are $@
echo The parameters passed in are $*

./foo.sh herp derp
The parameters passed in are herp derp
The parameters passed in are herp derp
  1. Ist eines dem anderen vorzuziehen?
  2. Warum gibt es zwei integrierte Variablen, die genau dasselbe tun?

Zusätzliche Quellen
bash.cyberciti.biz

Antwort1

Sie sind nicht dasselbe. $*ist ein einzelner String, wohingegen es $@sich um ein echtes Array handelt. Um den Unterschied zu sehen, führen Sie das folgende Skript wie folgt aus:

 > ./test.sh one two "three four"

Das Skript:

#!/bin/bash

echo "Using \"\$*\":"
for a in "$*"; do
    echo $a;
done

echo -e "\nUsing \$*:"
for a in $*; do
    echo $a;
done

echo -e "\nUsing \"\$@\":"
for a in "$@"; do
    echo $a;
done

echo -e "\nUsing \$@:"
for a in $@; do
    echo $a;
done              

Die Erklärung und die Ergebnisse für die vier Fälle finden Sie unten.

Im ersten Fall werden die Parameter als ein einziger langerzitiertZeichenfolge:

Using "$*":
one two three four

Fall 2 (ohne Anführungszeichen) – die Zeichenfolge wird durch die forSchleife in Wörter zerlegt:

Using $*:
one
two
three
four

Fall 3 – jedes Element von $@ wird als in Anführungszeichen gesetzter String behandelt:

Using "$@":
one
two
three four

Letzter Fall - jedes Element wird als Zeichenfolge ohne Anführungszeichen behandelt, sodass das letzte erneut durch Folgendes geteilt wird for three four:

Using $@:
one
two
three
four

Antwort2

Der Unterschied liegt in der Art und Weise der Erweiterung.

$*wird zu einem einzelnen Argument erweitert, wobei alle Elemente durch Leerzeichen getrennt sind (tatsächlich das erste Zeichen von $IFS).
$@wird zu mehreren Argumenten erweitert.

Zum Beispiel

#!/bin/bash
echo "With *:"
for arg in "$*"; do echo "<$arg>"; done
echo
echo "With @:"
for arg in "$@"; do echo "<$arg>"; done

 

$ /tmp/test.sh 1  2 "3  4"
With *:
<1 2 3  4>

With @:
<1>
<2>
<3  4>

Antwort3

Sie können überprüfenBash-Anfängerhandbuchfür weitere Informationen. Diese machen so ziemlich dasselbe, mit dem Unterschied, wie sie getrennt sind:

$*- Erweitert auf die Positionsparameter, beginnend bei 1. Wenn die Erweiterung in doppelten Anführungszeichen erfolgt, wird sie auf ein einzelnes Wort erweitert, wobei der Wert jedes Parameters durch das erste Zeichen der speziellen IFS-Variable getrennt ist.

$@- Erweitert die Positionsparameter, beginnend bei 1. Wenn die Erweiterung in Anführungszeichen erfolgt, wird jeder Parameter zu einem separaten Wort erweitert.

Wenn Sie jedoch keinen IFSanderen Wert als den Standardwert festlegen, könnte es identisch aussehen.

Antwort4

Ist eines dem anderen vorzuziehen?

Die kurze Antwort lautet "$@":

Wenn Sie sie ohne Anführungszeichen verwenden, sind sie gleich. In diesem Fall wird keins dem anderen vorgezogen. Ich schlage jedoch vor, sie immer mit Anführungszeichen zu verwenden, es sei denn, Sie wissen genau, was Sie wollen.

Warum gibt es zwei integrierte Variablen, die genau dasselbe tun?

Es gibt keinen Unterschied zwischen $*und $@, aber "$@"und "$*"haben.

Meine Antwort könnt ihr indieser Beitragum zu sehen, worin sie sich unterscheiden.

verwandte Informationen