Erklären Sie den Shell-Befehl: shift $ (($ optind - 1))

30

Ich bin kein Linux-Typ, sondern stecke in einem Skript, das ich für mein Projekt lesen muss. Kann mir jemand helfen, was dieser Befehl tut?

shift $(($optind - 1))
Gaurav Pant
quelle
3
Wie unten angegeben, muss OPTIND in Großbuchstaben geschrieben sein und das '$' in der Klammer ist optional.
DarkHeart

Antworten:

49

shift $((OPTIND-1))(Anmerkung OPTINDist Großbuchstaben) wird normalerweise unmittelbar nach einer getopts whileSchleife gefunden. $OPTINDist die Anzahl der von gefundenen Optionen getopts.

Genau genommen OPTINDgibt pauljohn32 in den Kommentaren die Position des nächsten Befehlszeilenarguments an.

Aus dem GNU Bash Referenzhandbuch :

getopts optstring name [Argumente]

getoptswird von Shell-Skripten zum Analysieren von Positionsparametern verwendet. optstringenthält die zu erkennenden Optionszeichen; Wenn auf ein Zeichen ein Doppelpunkt folgt, wird erwartet, dass die Option ein Argument enthält, das durch Leerzeichen von diesem getrennt sein muss. Der Doppelpunkt (':') und das Fragezeichen ('?') Dürfen nicht als Optionszeichen verwendet werden. Bei jedem Aufruf wird getoptsdie nächste Option in den Namen der Shell-Variablen eingefügt, initialisiert, namefalls nicht vorhanden, und der Index des nächsten zu verarbeitenden Arguments in die Variable OPTIND. OPTINDwird jedes Mal auf 1 initialisiert, wenn die Shell oder ein Shell-Skript aufgerufen wird. Wenn eine Option ein Argument erfordert, fügt getopts dieses Argument in die Variable ein OPTARG. Die Shell wird nicht zurückgesetztOPTIND automatisch; Es muss manuell zwischen mehreren Aufrufen getoptsinnerhalb desselben Shell-Aufrufs zurückgesetzt werden, wenn ein neuer Parametersatz verwendet werden soll.

Wenn das Ende der Optionen erreicht ist, wird getoptsmit einem Rückgabewert größer als Null beendet. OPTINDwird auf den Index des ersten Nicht-Options-Arguments gesetzt, und der Name wird auf '?'

getoptsAnalysiert normalerweise die Positionsparameter. Wenn jedoch mehr Argumente angegeben werden args, werden getoptsdiese stattdessen analysiert.

shift n
entfernt n Zeichenfolgen aus der Liste der Positionsparameter. So shift $((OPTIND-1))entfernt alle Optionen , die von analysiert wurden getoptsaus der Parameterliste, und so nach diesem Punkt, $1auf den ersten Nicht-Option Argument wird sich auf das Skript übergeben.

Aktualisieren

Wie mikeserv in dem Kommentar erwähnt, shift $((OPTIND-1))kann es unsicher sein. Um unerwünschte Worttrennungen usw. zu vermeiden, sollten alle Parametererweiterungen in doppelte Anführungszeichen gesetzt werden. Die sichere Form für den Befehl ist also

shift "$((OPTIND-1))"

PM 2Ring
quelle
Dies scheint nur dann richtig zu funktionieren, wenn alle Optionen vor den verbleibenden Positionsargumenten auftreten. Richtig?
Steve Jorgensen
@SteveJorgensen: Ja, das stimmt. OTOH: Das Setzen von Optionen nach Nichtoptionsargumenten verstößt gegen die sh / bash-Konvention. Im Allgemeinen bedeuten die ersten Argumente, die nicht mit einem Bindestrich beginnen, das Ende der Optionen, und alle nachfolgenden Argumente, die mit einem Bindestrich beginnen, gelten nicht als Optionen. Nicht alle Programme halten sich an diese Konvention, aber es macht das Leben viel einfacher, wenn Sie dies tun. :)
PM 2Ring
@SteveJorgensen: (Forts.) Dieses Thema wird kurz in Warum analysieren einige Dienstprogramme Operanden vor Optionen? . In Gilles 'Kommentar zu Celadas Antwort heißt es, dass manche Programme (wie find) so aussehen, als würden sie Optionen nach Nicht-Optionen zulassen, aber sie haben keine Operanden, die mit einem Bindestrich beginnen.
PM 2Ring
Danke für die Info (& die Bearbeitung) @mosvy Das ist ziemlich ungewöhnlich IFS, aber es ist besser, auf Nummer sicher zu gehen, als es zu tun. ;)
PM 2Ring
@roaima if IFS=0123456789, shift $((OPTIND-1))(ohne Anführungszeichen) verwandelt sich in shift ""das wird unbemerkt ignoriert (in ksh) oder erzeugt einen Fehler (in bashund dash).
Mosvy
8

$((...))berechnet nur Sachen. In Ihrem Fall nimmt es den Wert von $optintund subtrahiert 1.

shiftEntfernt Positionsparameter. In Ihrem Fall werden optint-1Parameter entfernt .

Für weitere Informationen einen Blick auf help getopts, help shift, Blick auf man bashfür „Arithmetic Expansion“, und vor allem Google für getopts.

michas
quelle