Wie der Kommentar von Goldlöckchen und die Referenzen der Menschheit beschreiben, werden
shiftdie Positionsparameter ( $1, $2usw.) neu zugewiesen , sodass $1der alte Wert von $2,
$2der Wert von $3usw. übernommen wird. *
Der alte Wert von $1wird verworfen. ( $0wird nicht geändert.) Einige Gründe dafür sind:
- Hiermit können Sie leichter auf das zehnte Argument zugreifen (sofern es eines gibt).
$10funktioniert nicht - es wird als $1verkettet mit einem interpretiert 0
(und könnte so etwas produzieren Hello0). Nach a shiftwird das zehnte Argument $9. (In den meisten modernen Shells können Sie jedoch verwenden ${10}.)
- Wie der Bash-Leitfaden für Anfänger zeigt, kann er zum Durchlaufen der Argumente verwendet werden. IMNSHO, das ist ungeschickt;
forist viel besser dafür.
- Wie in Ihrem Beispielskript können Sie alle Argumente mit Ausnahme einiger weniger auf die gleiche Weise verarbeiten. Beispiel: In Ihrem Skript sind
$1und $2Textzeichenfolgen, während $3und alle anderen Parameter Dateinamen sind.
So spielt es sich ab. Angenommen, Ihr Skript wird aufgerufen Patryk_scriptund heißt
Patryk_script USSR Russia Treaty1 Atlas2 Pravda3
Das Skript sieht
$1 = USSR
$2 = Russia
$3 = Treaty1
$4 = Atlas2
$5 = Pravda3
Die Anweisung ostr="$1"setzt die Variable ostrauf USSR. Die erste shiftAnweisung ändert die Positionsparameter wie folgt:
$1 = Russia
$2 = Treaty1
$3 = Atlas2
$4 = Pravda3
Die Anweisung nstr="$1"setzt die Variable nstrauf Russia. Die zweite shiftAnweisung ändert die Positionsparameter wie folgt:
$1 = Treaty1
$2 = Atlas2
$3 = Pravda3
Und dann die forSchleife Änderungen USSR( $ostr) zu Russia( $nstr) in den Akten Treaty1, Atlas2und Pravda3.
Es gibt einige Probleme mit dem Skript.
für Datei in $ @; machen
Wenn das Skript als aufgerufen wird
Patryk_script UdSSR Russland Vertrag1 "Weltatlas2" Pravda3
es sieht
$ 1 = UdSSR
$ 2 = Russland
$ 3 = Vertrag1
$ 4 = Weltatlas2
$ 5 = Pravda3
aber, weil $@nicht zitiert wird, in dem Raum World Atlas2ist nicht in Anführungszeichen gesetzt, und die forSchleife denkt , dass es vier Dateien hat: Treaty1, World, Atlas2, und Pravda3. Dies sollte auch so sein
für Datei in "$ @"; machen
(um Sonderzeichen in den Argumenten zu zitieren) oder einfach
für Datei zu tun
(was der längeren Version entspricht).
eval "sed 's /" $ ostr "/" $ nstr "/ g' $ file"
Dies ist nicht unbedingt erforderlich eval, und die Weitergabe ungeprüfter Benutzereingaben an evalkann gefährlich sein. Zum Beispiel, wenn das Skript als aufgerufen wird
Patryk_script "'; rm *;'" Russland-Vertrag1 Atlas2 Pravda3
es wird ausgeführt rm *! Dies ist ein großes Problem, wenn das Skript mit höheren Berechtigungen ausgeführt werden kann als die des Benutzers, der es aufruft. Zum Beispiel, wenn es über sudoeine Weboberfläche ausgeführt oder von dieser aufgerufen werden kann. Es ist wahrscheinlich nicht so wichtig, wenn Sie es nur als Sie selbst in Ihrem Verzeichnis verwenden. Aber es kann geändert werden
sed "s / $ ostr / $ nstr / g" "$ file"
Dies birgt immer noch einige Risiken, die jedoch viel weniger schwerwiegend sind.
if [ -f $file ], > $file.tmpUnd mv $file.tmp $file
sollte es sein if [ -f "$file" ], > "$file.tmp"und mv "$file.tmp" "$file"jeweils mit Dateinamen umgehen , die Leerzeichen (oder andere lustige Zeichen) in ihnen haben könnte. (Mit dem eval "sed …Befehl werden auch Dateinamen mit Leerzeichen entstellt.)
* shift akzeptiert ein optionales Argument: eine positive Ganzzahl, die angibt, wie viele Parameter verschoben werden sollen. Der Standardwert ist eins ( 1). Zum Beispiel shift 4verursacht $5
zu werden $1,
$6zu werden $2und so weiter. (Beachten Sie, dass das Beispiel im Bash-Handbuch für Anfänger falsch ist.) Daher kann Ihr Skript geändert werden
ostr="$1"
nstr="$2"
shift 2
was als klarer angesehen werden könnte.
Endnote / Warnung:
Die Windows-Eingabeaufforderungssprache (Batch-Datei) unterstützt auch einen SHIFTBefehl, der im Grunde das Gleiche wie der shiftBefehl in Unix-Shells tut , mit einem auffälligen Unterschied, den ich verstecke, um zu verhindern, dass die Benutzer dadurch verwirrt werden:
- Ein Befehl wie
SHIFT 4ist ein Fehler, der die Fehlermeldung "Ungültiger Parameter für SHIFT-Befehl" ausgibt.
SHIFT /n, wobei neine ganze Zahl zwischen 0 und 8 ist, ist gültig - aber es werden keine Zeiten verschoben . Es verschiebt sich einmal, beginnend mit dem n- ten Argument. Dies bewirkt, dass (das fünfte Argument) zu wird und so weiter, wobei die Argumente 0 bis 3 allein bleiben.n SHIFT /4%5%4,
%6%5
pushdundpopd).