Ich schreibe ein sehr einfaches Skript, das ein anderes Skript aufruft, und ich muss die Parameter von meinem aktuellen Skript auf das Skript übertragen, das ich ausführe.
Zum Beispiel ist mein Skriptname foo.sh
und ruft aufbar.sh
foo.sh:
bar $1 $2 $3 $4
Wie kann ich dies tun, ohne jeden Parameter explizit anzugeben?
bash
command-line-arguments
Fragsworth
quelle
quelle
Antworten:
Verwenden Sie
"$@"
statt einfach,$@
wenn Sie tatsächlich möchten, dass Ihre Parameter gleich übergeben werden.Beobachten:
quelle
'arg with spaces'
für die drei Beispiele ein einfügen. Ich war von den Ergebnissen überrascht; hoffentlich kannst du sie erklären../foo.sh "arg with spaces"
und./foo.sh 'arg with spaces'
sind zu 100% identisch, daher sehe ich nicht, wie der Vorschlag, es zu den angegebenen Beispielen hinzuzufügen, hilfreich wäre.Für Bash und andere Bourne-ähnliche Muscheln:
quelle
$argv:q
funktioniert es in einigen csh-Varianten.exec java com.myserver.Program "$@"
erstellen. Dies führt dazu, dass Bash in Java ausgeführt wird, anstatt zu warten, bis es abgeschlossen ist. Sie verwenden also einen Prozesssteckplatz weniger. Wenn der übergeordnete Prozess (der Ihr Skript ausgeführt hat) es über die PID überwacht und erwartet, dass es sich um den Java-Prozess handelt, können einige ungewöhnliche Dinge beschädigt werden, wenn Sie keine Exec ausführen. Die Ausführung bewirkt, dass Java dieselbe PID erbt.args=("$@")
und erweitern jedes Element als separate Schale „Wort“ ( ähnlich wie"$@"
) mit"${args[@]}"
."$@"
sind. Wird dies fehlschlagen, wenn Sie Leerzeichen in einem Argument oder Nullzeichen oder andere Sonderzeichen maskiert haben?Verwendung
"$@"
(funktioniert für alle POSIX- kompatiblen Geräte ).Von Bash mit gutem Beispiel .
quelle
$*
. Ich glaube, hier gibt es historische Fortschritte.$*
funktionierte nicht wie geplant, wurde also$@
erfunden, um es zu ersetzen; Da die Anführungszeichen jedoch so sind, wie sie sind, sind die doppelten Anführungszeichen weiterhin erforderlich (oder es wird auf die fehlerhafte$*
Semantik zurückgegriffen).echo "$@"
as enthält, erhalten./script.sh a "b c" d
Siea b c d
stattdessen statta "b c" d
, was sehr unterschiedlich ist.echo
drei Argumente erhält:"a" "b c" "d"
(dann verbindet die Shell sie als Teil ihrer Zeichenfolgenerweiterung). Aber wenn du benutzt hättest,for i in "$@"; do echo $i; done
hättest du bekommena⏎b c⏎d
.Mir ist klar, dass dies gut beantwortet wurde, aber hier ist ein Vergleich zwischen "$ @" $ @ "$ *" und $ *
Inhalt des Testskripts:
Führen Sie nun das Testskript mit verschiedenen Argumenten aus:
quelle
Ich dachte nur, dies könnte etwas nützlicher sein, wenn Sie versuchen zu testen, wie Argumente in Ihr Skript gelangen
quelle
$#
""
,''
als Argument, auch wenn es keine Args gab, ist es still. Ich habe versucht, dies zu beheben, brauche aber eine for-Schleife und einen Zähler mit$#
. Ich habe dies gerade am Ende hinzugefügt:echo "End of args or received quoted null"
Mein SUN Unix hat viele Einschränkungen, sogar "$ @" wurde nicht wie gewünscht interpretiert. Meine Problemumgehung ist $ {@}. Zum Beispiel,
Übrigens musste ich dieses spezielle Skript haben, da mein Unix auch grep -r nicht unterstützt
quelle
ksh
Wenn Sie
$@
eine Zeichenfolge in Anführungszeichen mit anderen Zeichen einfügen, ist das Verhalten bei mehreren Argumenten sehr merkwürdig. In den Anführungszeichen ist nur das erste Argument enthalten.Beispiel:
Ausbeuten:
Aber zuerst einer anderen Variablen zuweisen:
Ausbeuten:
quelle
"$@"
in bash. Es hilft auch dabei, den Hauptunterschied zwischen$@
und zu veranschaulichen$*
und warum beide nützlich sind. Imbash(1)
Abschnitt Spezielle Parameter auf der Manpage: "*
- Wenn die Erweiterung in doppelten Anführungszeichen erfolgt, wird sie zu einem einzelnen Wort mit dem Wert jedes Parameters erweitert […] Das heißt,"$*"
entspricht ["$1c$2c..."
woc
ist [$IFS
]." In der Tat hätte die Verwendung$*
anstelle von$@
in Ihrem ersten Beispiel die Ausgabe identisch mit der zweiten Version gebracht."$@"
. Nochmals aus der Manpage: "@
- Wenn die Erweiterung in doppelten Anführungszeichen erfolgt, wird jeder Parameter zu einem separaten Wort erweitert. Dies"$@"
entspricht"$1"
"$2"
... Wenn die Erweiterung in doppelten Anführungszeichen innerhalb eines Wortes erfolgt, wird die Erweiterung des ersten Parameters verbunden mit dem Anfangsteil des ursprünglichen Wortes, und die Erweiterung des letzten Parameters wird mit dem letzten Teil des ursprünglichen Wortes verbunden. " ... Und in der Tat, wenn Ihr Code gewesen wärebash -c "true foo $@ bar baz"
, dann führen Sie ihn wietest.sh one two
net ausbash -c 'true foo one' 'two bar baz'
.$*
, ich scheine zu vergessen, dass es existiert ..$@
gerade erst an Fahrt gewonnen, als ich mit dem Shell-Scripting angefangen habe. Ich muss mich immer noch daran erinnern, dass es da ist. Es war üblich, die"$*"
Verwendung in Skripten zu sehen ... dann erkannte der Autor, dass alle ihre Argumente zusammengeschlagen wurden, sodass sie alle Arten von komplexem Unsinn mit Wortteilung"$*"
versuchten oder eine Argumentliste durch Schleifen [neu] zusammenstellten rübershift
, um sie eins nach dem anderen herunterzuziehen ... nur mit$@
löst es. (Hilft, dass Bash dieselbe Mnemonik verwendet, um auch auf Array-Mitglieder zuzugreifen:${var[*]}
für sie alle als Wort,${var[@]}
für eine Liste von Wörtern.)bash -c
auf eine Weise verwenden, die absolut keinen Sinn ergibt .Manchmal möchten Sie alle Ihre Argumente zu übergeben, aber voraus durch ein Flag (zB
--flag
)Sie können dies folgendermaßen tun:
Hinweis: Um eine zusätzliche Feldaufteilung zu vermeiden, müssen Sie
%s
und zitieren.$@
Um eine einzelne Zeichenfolge zu vermeiden, können Sie die Unterschale von nicht zitierenprintf
.quelle
Funktioniert einwandfrei, außer wenn Sie Leerzeichen oder maskierte Zeichen haben. Ich finde in diesem Fall keine Möglichkeit, Argumente zu erfassen und an ein SSH innerhalb des Skripts zu senden.
Dies könnte nützlich sein, ist aber so hässlich
quelle
Viele Antworten hier empfehlen
$@
oder$*
mit und ohne Anführungszeichen, jedoch scheint keine zu erklären, was diese wirklich tun und warum Sie dies tun sollten. Lassen Sie mich diese hervorragende Zusammenfassung aus dieser Antwort stehlen :Beachten Sie, dass Anführungszeichen den Unterschied ausmachen und ohne sie beide dasselbe Verhalten haben.
Für meinen Zweck musste ich Parameter von einem Skript an ein anderes übergeben, wie es ist, und dafür ist die beste Option:
Beachten Sie keine Anführungszeichen und
$@
sollten auch in der obigen Situation funktionieren.quelle
bar "$@"
wird gleichbedeutend sein mitbar "$1" "$2" "$3" "$4"
Beachten Sie, dass die Anführungszeichen wichtig sind!
"$@"
,$@
,"$*"
Oder$*
wird jeder verhalten sich etwas anders in Bezug auf Flucht und Verkettung wie in diesem beschrieben Stackoverflow Antwort .Ein eng verwandter Anwendungsfall besteht darin , alle angegebenen Argumente in einem Argument wie diesem zu übergeben:
bash -c "bar \"$1\" \"$2\" \"$3\" \"$4\""
.Ich benutze eine Variation von @ kvantours Antwort, um dies zu erreichen:
bash -c "bar $(printf -- '"%s" ' "$@")"
quelle