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