Wie ändere ich ein Kommandozeilenargument in Bash?

92

Gibt es eine Möglichkeit, die Befehlszeilenargumente in einem Bash-Skript zu ändern? Angenommen, ein Bash-Skript wird folgendermaßen aufgerufen:

./foo arg1 arg2  

Gibt es eine Möglichkeit, den Wert von arg1 im Skript zu ändern? Sagen wir so etwas wie

$1="chintz"
Sriram
quelle

Antworten:

147

Sie müssen alle Argumente zurücksetzen. Zum Ändern zB $3:

$ set -- "${@:1:2}" "new" "${@:4}"

Grundsätzlich Sie setzen alle Argumente auf ihre aktuellen Werte, mit Ausnahme des einen (n) , die Sie ändern möchten. set --wird auch von POSIX 7 spezifiziert .

Die "${@:1:2}"Notation wird auf die beiden (daher 2in der Notation) Positionsargumente erweitert, beginnend mit dem Offset 1(dh $1). Es ist eine Abkürzung für "$1" "$2"in diesem Fall, aber es ist viel nützlicher, wenn Sie z "${17}".

thkala
quelle
1
Also, um $ 3 zu ändern, muss ich auch $ 1 und $ 2 ändern, oder? Und ändern Sie sie zu was? Was bedeutet "Zurücksetzen"?
Sriram
Danke für den Trick! Ich hatte Schwierigkeiten, dies für Dateinamen mit eingebetteten Leerzeichen zu verwenden. Versuchen Sie für alle anderen, die auf dieses Problem stoßen könnten, diesbezüglich ganzeval vorne mitzumachen .
cxw
2
Dies ist in Ordnung, wenn Sie die Position des Parameters kennen, den Sie ändern möchten. Was ist, wenn Sie es tatsächlich nicht wissen und es dynamisch ändern müssen? Ich habe es mit $ set - "$ {: 1: $ pivot}" versucht, aber dort wird keine Variable akzeptiert.
Daniele Segato
1
Wie kann ich innerhalb einer Funktion dasselbe tun? Ihre Lösung scheint nicht zu funktionieren, wenn sie innerhalb einer Funktion aufgerufen wird.
Hashken
2
Sie können die Positionsparameter eines Skripts nicht innerhalb einer Funktion ändern - die eigenen Argumente der Funktion verbergen sie. Sie können sie jedoch in einem Array speichern und damit arbeiten.
Thkala
22

Die Optimierung für die Lesbarkeit und Wartbarkeit, können Sie besser dran , die Zuweisung $1und $2zu sinnvollen Variablen (ich weiß nicht, input_filename = $1und output_filename = $2oder etwas) und dann mindestens eine der Variablen zu überschreiben ( input_filename = 'chintz'), so dass die Eingabe in das Skript unverändert, falls es ist woanders gebraucht.

Johnsyweb
quelle
Ich wollte einen Ansatz, bei dem ich eines der Eingabeargumente selbst ändern kann. Ich musste das tun, da ich einen Wert aus dem Skript zurückgeben wollte. Die von thkala vorgeschlagene Antwort funktionierte gut. Danke für die Antwort!!!
Sriram
3
@ Johnsyweb Einverstanden. Aus Gründen der Lesbarkeit ist Ihre Methode die bessere.
Dss
1
"Sie sind besser dran" hängt immer vom Anwendungsfall ab, der nicht bereitgestellt wird.
Scott
2
@Scott 7 Jahre älter und mehr Erfahrung als ich, als ich diese Antwort schrieb, bin ich geneigt, Ihnen zuzustimmen.
Johnsyweb
Beispiel, bei dem dies nicht funktionieren würde (abgesehen von der Verwendung von $ FIRST_PARAMETER): Verwendung und Bedeutung des Parameters in Abhängigkeit vom tatsächlichen Wert.
Igor Stoppa