GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Bash -c mit Positionsparametern?

Normalerweise $0 in einem Skript wird auf den Namen des Skripts gesetzt oder auf den Namen, unter dem es aufgerufen wurde (einschließlich des Pfads). Wenn ich jedoch bash verwende mit dem -c Option, $0 wird auf das erste der Argumente gesetzt, die nach der Befehlszeichenfolge übergeben werden:

bash -c 'echo $0' foo bar 
# foo 

Tatsächlich scheint es, als ob Positionsparameter verschoben wurden, aber einschließlich $0 . Allerdings shift in der Befehlszeichenfolge wirkt sich nicht auf $0 aus (wie gewohnt):

bash -c 'echo $0; shift; echo $0' foo bar
# foo
# foo

Warum dieses anscheinend seltsame Verhalten für Befehlszeichenfolgen?
Beachten Sie, dass ich nach dem Grund, der Begründung für die Implementierung eines solchen seltsamen Verhaltens suche.

Man könnte spekulieren, dass eine solche Befehlszeichenfolge das $0 nicht benötigt Parameter wie gewöhnlich definiert, daher wird er aus Spargründen auch für normale Argumente verwendet. Allerdings ist in diesem Fall das Verhalten von shift ist ungerade. Eine andere Möglichkeit ist, dass $0 wird verwendet, um das Verhalten von Programmen zu definieren (a la bash aufgerufen als sh oder vim aufgerufen als vi ), aber das kann nicht sein, da $0 hier wird nur in der Befehlszeichenfolge und nicht von darin aufgerufenen Programmen gesehen. Mir fällt keine andere Verwendung für $0 ein , daher kann ich das nicht erklären.

Akzeptierte Antwort:

Das gibt Ihnen die Möglichkeit, $0 einzustellen/auszuwählen bei Verwendung eines Inline-Skripts. Andernfalls $0 wäre nur bash .

Dann können Sie zum Beispiel Folgendes tun:

$ echo foo > foo
$ bash -c 'wc -c < "${1?}"' getlength foo
4
$ rm -f bar
$ bash -c 'wc -c < "${1?}"' getlength bar
getlength: bar: No such file or directory
$ bash -c 'wc -c < "${1?}"' getlength
getlength: 1: parameter not set

Früher haben das nicht alle Muscheln gemacht. Die Bourne-Shell tat es. Die Korn- (und Almquist-) Shell entschied sich dafür, dass der erste Parameter an $1 geht stattdessen. POSIX ging schließlich den Bourne-Weg, also ksh und ash Derivate haben später darauf zurückgegriffen (mehr dazu unter http://www.in-ulm.de/~mascheck/various/find/#shell). Das bedeutete das lange Zeit für sh (die je nach System auf der Bourne-, Almquist- oder Korn-Shell basierten), wussten Sie nicht, ob das erste Argument in $0 ging oder $1 , also mussten Sie für die Portabilität Dinge tun wie:

sh -c 'echo foo in "$1"' foo foo

Oder:

sh -c 'shift "$2"; echo txt files are "[email protected]"' tentative-arg0 3 2 *.txt

Glücklicherweise hat POSIX das neue Verhalten spezifiziert, bei dem das erste Argument in $0 geht , also können wir jetzt portabel Folgendes tun:

sh -c 'echo txt files are "[email protected]"' meaningful-arg0-for-error *.txt

Linux
  1. Bash-Arrays mit Beispielen

  2. Bash-If-Else-Anweisung mit Beispielen

  3. Basisname mit Leerzeichen in einem Bash-Skript?

  4. Linux Bash XMLLINT mit XPATH

  5. Runden von Zahlen mit bc in Bash

Was ist Git Bash? Arbeiten mit Git Bash-Befehlen

So schreiben Sie ein Bash-Skript mit Beispielen

Bash HereDoc Tutorial mit Beispielen

So erstellen Sie Dokumente mit Bash-Skripten

Bash If Else Syntax mit Beispielen

Sortieren von Zahlen mit mehreren Dezimalstellen in Bash