985 Stimmen

Wie kann ich alle Argumente, die an mein Bash-Skript übergeben werden, an eine Funktion von mir weitergeben?

Nehmen wir an, ich habe eine function abc() die die Logik für die Analyse der an mein Skript übergebenen Argumente übernimmt.

Wie kann ich alle Argumente, die mein Bash-Skript erhalten hat, an es weitergeben? Die Anzahl der Parameter ist variabel, so dass ich nicht nur hardcode die Argumente wie diese übergeben:

abc $1 $2 $3 $4

Editar . Besser noch: Gibt es eine Möglichkeit für meine Funktion, auf die Variablen der Skriptargumente zuzugreifen?

3 Stimmen

Mögliches Duplikat von Alle Argumente in einem Bash-Shell-Skript weitergeben . (Diese Frage wurde eigentlich vor der hier verlinkten Frage gestellt. Aber die Frage im Link hat detailliertere Antworten und einen informativeren Titel und eignet sich vielleicht besser als Referenzfrage)

1646voto

Gordon Davisson Punkte 105638

El $@ wird auf alle durch Leerzeichen getrennten Befehlszeilenparameter erweitert. Hier ist ein Beispiel.

abc "$@"

Bei der Verwendung von $@ sollten Sie (fast) immer in Anführungszeichen setzen, um zu vermeiden, dass Argumente, die Leerzeichen oder Platzhalter enthalten, falsch interpretiert werden (siehe unten). Dies funktioniert für mehrere Argumente. Es ist auch auf alle POSIX-kompatiblen Shells portierbar.

Es ist auch erwähnenswert, dass $0 (im Allgemeinen der Name oder der Pfad des Skripts) nicht in $@ .

El Bash-Referenzhandbuch Abschnitt Spezielle Parameter sagt, dass $@ expandiert zu den Positionsparametern, beginnend bei eins. Wenn die Expansion innerhalb von doppelten Anführungszeichen erfolgt, wird jeder Parameter zu einem separaten Wort expandiert. Das bedeutet "$@" ist gleichbedeutend mit "$1" "$2" "$3"... .

Weitergabe un peu de Argumente:

Wenn Sie Folgendes bestehen wollen alle bis auf den ersten Argumenten können Sie zunächst mit shift um das erste Argument zu "verbrauchen" und dann "$@" um die restlichen Argumente an einen anderen Befehl zu übergeben. In der bash (und zsh und ksh, aber nicht in einfachen POSIX-Shells wie dash) können Sie dies tun, ohne die Argumentliste durcheinander zu bringen, indem Sie eine Variante des Array-Slicing verwenden: "${@:3}" liefert Ihnen die Argumente, die mit "$3" . "${@:3:4}" erhalten Sie bis zu vier Argumente, beginnend bei "$3" (d.h. "$3" "$4" "$5" "$6" ), wenn so viele Argumente übergeben wurden.

Dinge, die Sie wahrscheinlich nicht tun wollen:

"$*" gibt alle Argumente in einer einzigen Zeichenkette wieder (getrennt durch Leerzeichen, oder was auch immer das erste Zeichen von $IFS ist). Dadurch wird die Unterscheidung zwischen Räumen innerhalb Argumente und die Leerzeichen zwischen Argumente, ist also generell eine schlechte Idee. Obwohl es für das Drucken der Argumente in Ordnung sein könnte, z.B. echo "$*" vorausgesetzt, es ist Ihnen nicht wichtig, den Raum innerhalb/zwischen den Unterscheidungen zu bewahren.

Zuweisung der Argumente an eine reguläre Variable (wie in args="$@" ) fügt alle Argumente zusammen wie "$*" tut. Wenn Sie die Argumente in einer Variablen speichern wollen, verwenden Sie ein Array mit args=("$@") (durch die Klammern handelt es sich um ein Array), und verweisen Sie dann auf sie, z. B. "${args[0]}" usw. Beachten Sie, dass in bash und ksh Array-Indizes bei 0 beginnen, also $1 wird in args[0] usw. zsh hingegen beginnt die Array-Indizes bei 1, so dass $1 wird in args[1] . Und einfachere Shells wie Dash haben überhaupt keine Arrays.

Die Anführungszeichen weglassen, entweder mit $@ ou $* versucht, jedes Argument in einzelne Wörter aufzuteilen (basierend auf Leerzeichen oder was auch immer in $IFS ) und versuchen außerdem, alles, was wie ein Platzhalter für einen Dateinamen aussieht, in eine Liste passender Dateinamen zu erweitern. Dies kann wirklich seltsame Auswirkungen haben und sollte fast immer vermieden werden. (Außer in zsh, wo diese Expansion standardmäßig nicht stattfindet).

4 Stimmen

Lesen Sie hier mehr darüber, warum es wichtig ist, das Doppel " zu haben: stackoverflow.com/a/4824637/4575793

1 Stimmen

"${@:3}" scheint nicht zu funktionieren mit zsh .

0 Stimmen

@Bibi Bei mir funktioniert es in zsh (v 5.3), sowohl in Skripten als auch in Funktionen. Wie testen Sie es?

170voto

hajamie Punkte 2728

Ich brauchte eine Abwandlung davon, von der ich annehme, dass sie für andere nützlich sein wird:

function diffs() {
        diff "${@:3}" <(sort "$1") <(sort "$2")
}

El "${@:3}" Diese Funktion implementiert also einen sortierten Vergleich, indem sie die ersten beiden Argumente durch sort an diff weitergibt und dann alle anderen Argumente an diff weitergibt, so dass Sie sie ähnlich wie diff aufrufen können:

diffs file1 file2 [other diff args, e.g. -y]

17 Stimmen

Le site "${@:3}" eignet sich auch hervorragend für Skripte, die Argumente haben, aber auch Argumente an andere Skripte übergeben können, die sie aufrufen. Ein Projekt von mir hat zum Beispiel ein Skript, mit dem man das Programm einfach ausführen kann, mit einem Argument für die zu verwendende Hauptklasse. Dann "${@:2}" kann verwendet werden, um die restlichen Argumente an diesen Einstiegspunkt zu übergeben.

13 Stimmen

@Kat hat dies bereits erwähnt, aber zur Klarstellung (falls Sie noch Zweifel haben): command "$@" ist gleichbedeutend mit command $1 "${@:2}" .

2 Stimmen

OMG! ICH Kuss Sie!

71voto

Mia Clarke Punkte 7963

Verwenden Sie die $@ die sich auf alle durch Leerzeichen getrennten Befehlszeilenparameter ausdehnt.

abc "$@"

0 Stimmen

Dadurch werden die Argumente in Anführungszeichen allerdings in separate Argumente aufgeteilt, was in den seltensten Fällen das ist, was man erwartet, wenn man ein Skript ausführt.

2 Stimmen

Nein, mein Fehler. Es funktioniert, wenn Sie den $@ in Anführungszeichen setzen, wie in Ihrem Beispiel, aber nicht, wenn Sie ihn ohne Anführungszeichen verwenden, wie im beschreibenden Text.

67voto

Giuseppe Cardone Punkte 5133

Hier ist ein einfaches Skript:

#!/bin/bash

args=("$@")

echo Number of arguments: $#
echo 1st argument: ${args[0]}
echo 2nd argument: ${args[1]}

$# ist die Anzahl der Argumente, die das Skript erhält. Ich finde es einfacher, auf sie mit einem Array zuzugreifen: die args=("$@") Zeile setzt alle Argumente in die args Array. Um auf sie zuzugreifen, verwenden Sie ${args[index]} .

3 Stimmen

Wäre es ${args[0]} für das erste Argument :o

3 Stimmen

Welchen Vorteil hat die Übergabe von $@ in ein Array gegenüber dem einfachen Aufruf der Argumente nach Index (z. B. $1)?

0 Stimmen

Abstimmung mit der Vereinbarung mit @King, dass dies Array bei [0] für das erste Element sein muss.

50voto

robstarbuck Punkte 4928

Es ist erwähnenswert, dass Sie mit dieser Syntax Argumentbereiche angeben können.

function example() {
    echo "line1 ${@:1:1}"; #First argument
    echo "line2 ${@:2:1}"; #Second argument
    echo "line3 ${@:3}"; #Third argument onwards
}

Ich hatte das noch nicht erwähnt gesehen.

3 Stimmen

Sie können einfach Folgendes verwenden $1 , $2 ... für die ersten beiden

0 Stimmen

@rubo77 Ich habe den Wortlaut meiner Antwort dahingehend korrigiert, dass "Reichweite" enthalten ist, danke.

0 Stimmen

Danke, das ist genau das, was ich für die Indexierung brauchte $@ mit einer Variablen

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