Wenn sie nicht zitiert werden $*
und gleich $@
sind. Sie sollten keines von beiden verwenden, da sie unerwartet abbrechen können, sobald Sie Argumente haben, die Leerzeichen oder Platzhalter enthalten.
"$*"
wird zu einem einzigen Wort erweitert "$1c$2c..."
. Normalerweise c
ist es ein Leerzeichen, aber es ist tatsächlich das erste Zeichen von IFS
, also kann es alles sein, was Sie wählen.
Die einzige gute Verwendung, die ich jemals dafür gefunden habe, ist:
Argumente mit Komma verbinden (einfache Version)
join1() {
typeset IFS=,
echo "$*"
}
join1 a b c # => a,b,c
Argumente mit dem angegebenen Trennzeichen verbinden (bessere Version)
join2() {
typeset IFS=$1 # typeset makes a local variable in ksh (see footnote)
shift
echo "$*"
}
join2 + a b c # => a+b+c
"$@"
erweitert, um Wörter zu trennen: "$1"
"$2"
...
Das ist fast immer was Sie wollen. Es erweitert jeden Positionsparameter zu einem eigenen Wort, wodurch es sich perfekt eignet, um Befehlszeilen- oder Funktionsargumente aufzunehmen und sie dann an einen anderen Befehl oder eine andere Funktion weiterzuleiten. Und weil es mit doppelten Anführungszeichen erweitert wird, bedeutet dies, dass Dinge nicht kaputt gehen, wenn sie beispielsweise "$1"
ein Leerzeichen oder ein Sternchen ( *
) enthalten.
Lassen Sie uns ein Skript namens schreiben svim
, das vim
mit läuft sudo
. Wir werden drei Versionen machen, um den Unterschied zu veranschaulichen.
svim1
#!/bin/sh
sudo vim $*
svim2
#!/bin/sh
sudo vim "$*"
svim3
#!/bin/sh
sudo vim "$@"
Für einfache Fälle, z. B. einen einzelnen Dateinamen, der keine Leerzeichen enthält, sind alle in Ordnung:
svim1 foo.txt # == sudo vim foo.txt
svim2 foo.txt # == sudo vim "foo.txt"
svim2 foo.txt # == sudo vim "foo.txt"
Aber nur $*
und "$@"
richtig arbeiten, wenn Sie mehrere Argumente haben.
svim1 foo.txt bar.txt # == sudo vim foo.txt bar.txt
svim2 foo.txt bar.txt # == sudo vim "foo.txt bar.txt" # one file name!
svim3 foo.txt bar.txt # == sudo vim "foo.txt" "bar.txt"
Und nur "$*"
und "$@"
richtig funktionieren, wenn Sie Argumente haben, die Leerzeichen enthalten.
svim1 "shopping list.txt" # == sudo vim shopping list.txt # two file names!
svim2 "shopping list.txt" # == sudo vim "shopping list.txt"
svim3 "shopping list.txt" # == sudo vim "shopping list.txt"
So "$@"
funktioniert nur die ganze Zeit richtig.
typeset
So erstellen Sie eine lokale Variable in ksh
( bash
und ash
verwenden sie local
stattdessen). Es bedeutet IFS
, dass der vorherige Wert wiederhergestellt wird, wenn die Funktion zurückkehrt. Dies ist wichtig, da die Befehle, die Sie anschließend ausführen, möglicherweise nicht ordnungsgemäß funktionieren, wenn sie IFS
auf einen nicht standardmäßigen Wert festgelegt sind.