1230 Stimmen

Alle Argumente in einem Bash-Shell-Skript übergeben.

Ich schreibe ein sehr einfaches Skript, das ein anderes Skript aufruft, und ich muss die Parameter von meinem aktuellen Skript zum auszuführenden Skript übertragen.

Zum Beispiel heißt mein Skript foo.sh und ruft bar.sh auf.

foo.sh:

bar $1 $2 $3 $4

Wie kann ich das machen, ohne jeden Parameter explizit anzugeben?

0 Stimmen

0 Stimmen

Ich musste diese Lösung für meinen Anwendungsfall verwenden.

40voto

Gregory Patmore Punkte 1094
#!/usr/bin/env bash
while [ "$1" != "" ]; do
  echo "Empfangen: ${1}" && shift;
done;

Dachte nur, dass dies nützlicher sein könnte, wenn Sie versuchen, wie Argumente in Ihr Skript gelangen, zu testen

7 Stimmen

Dies hat definitiv nicht dabei geholfen, seine Frage zu beantworten, aber es ist tatsächlich nützlich. Hochgewertet!

2 Stimmen

Es bricht ab, wenn ein leerer Parameter übergeben wird. Du solltest auf $# prüfen.

0 Stimmen

Guter Args-Tester, stimmen Sie "" und '' als Argument zu, auch wenn keine Args vorhanden waren, bleibt er still. Ich habe versucht, dies zu reparieren, aber es benötigt eine for-Schleife und einen Zähler mit $#. Ich habe dies einfach am Ende hinzugefügt: echo "Ende der Args oder erhielt ein zitiertes Null"

8voto

ColinM Punkte 12601

Wenn Sie $@ in einem in Anführungszeichen stehenden String zusammen mit anderen Zeichen einfügen, ist das Verhalten sehr seltsam, wenn es mehrere Argumente gibt, nur das erste Argument wird innerhalb der Anführungszeichen eingeschlossen.

Beispiel:

#!/bin/bash
set -x
bash -c "true foo $@"

Ergebnis:

$ bash test.sh bar baz
+ bash -c 'true foo bar' baz

Aber wenn Sie es zuerst in eine andere Variable zuweisen:

#!/bin/bash
set -x
args="$@"
bash -c "true foo $args"

Ergebnis:

$ bash test.sh bar baz
+ args='bar baz'
+ bash -c 'true foo bar baz'

4 Stimmen

Ich werde nicht leugnen, dass das beunruhigend ist, aber es ergibt tatsächlich Sinn innerhalb der Semantik von "$@" in bash. Es hilft auch, den entscheidenden Unterschied zwischen $@ und $* zu verdeutlichen, und warum sie beide nützlich sind. Aus dem Abschnitt Spezielle Parameter der bash(1) Man-Seite: "* — Wenn die Erweiterung innerhalb von doppelten Anführungszeichen erfolgt, erweitert es sich zu einem einzelnen Wort mit dem Wert jedes Parameters [...] Das heißt, "$*" ist äquivalent zu "$1c$2c...", wobei c [$IFS] ist." Und tatsächlich hätte die Verwendung von $* anstelle von $@ in Ihrem ersten Beispiel eine Ausgabe erbracht, die identisch mit der zweiten Version ist.

2 Stimmen

Jetzt vergleichen Sie das mit "$@". Wieder aus der Manpage: "@ - Wenn die Erweiterung innerhalb von doppelten Anführungszeichen erfolgt, wird jeder Parameter zu einem separaten Wort erweitert. Das heißt, "$@" entspricht "$1" "$2" ... Wenn die doppelte Erweiterung in einem Wort erfolgt, wird die Erweiterung des ersten Parameters mit dem Anfangsteil des ursprünglichen Worts verbunden, und die Erweiterung des letzten Parameters wird mit dem letzten Teil des ursprünglichen Worts verbunden." ...Und tatsächlich, wenn Ihr Code bash -c "true foo $@ bar baz" gewesen wäre, dann würde das Ausführen als test.sh eins zwei das Ergebnis bash -c 'true foo eins' 'zwei bar baz' ergeben.

1 Stimmen

Danke für die Dokumentenzitation und die Informationen über $*, ich scheine zu vergessen, dass es existiert.

6voto

Hampden123 Punkte 1228

Mein SUN Unix hat viele Einschränkungen, selbst "$@" wurde nicht wie gewünscht interpretiert. Mein Workaround ist ${@}. Zum Beispiel,

#!/bin/ksh
find ./ -type f | xargs grep "${@}"

Übrigens, ich musste dieses spezielle Skript haben, weil mein Unix auch kein grep -r unterstützt

4 Stimmen

Dies ist eine Bash-Frage; du benutzt ksh

6voto

kvantour Punkte 22682

Manchmal möchten Sie alle Argumente übergeben, aber mit einer Flagge versehen (z.B. --flag)

$ bar --flag "$1" --flag "$2" --flag "$3"

Sie können dies auf folgende Weise tun:

$ bar $(printf -- ' --flag "%s"' "$@")

Hinweis: Um zusätzliches Feldzerlegen zu vermeiden, müssen Sie %s und $@ in Anführungszeichen setzen, und um zu verhindern, dass eine einzelne Zeichenfolge entsteht, dürfen Sie das Unter-Shell von printf nicht in Anführungszeichen setzen.

1 Stimmen

Das funktioniert nicht, wenn Argumente " enthalten könnten - Sie müssen wirklich eine printf verwenden, die %q unterstützt.

5voto

Davidiusdadi Punkte 452

bar "$@" wird äquivalent zu bar "$1" "$2" "$3" "$4" sein

Beachten Sie, dass die Anführungszeichen wichtig sind!

"$@", $@, "$*" oder $* werden sich jeweils etwas unterschiedlich verhalten in Bezug auf Escapen und Konkatenation, wie in dieser stackoverflow Antwort beschrieben.

Ein eng verwandter Anwendungsfall ist alle übergebenen Argumente innerhalb eines Arguments zu übergeben wie folgt:

bash -c "bar \"$1\" \"$2\" \"$3\" \"$4\"".

Ich verwende eine Variation von @kvantours Antwort, um dies zu erreichen:

bash -c "bar $(printf -- '"%s" ' "$@")"

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X