Was macht $ {0% / *} in Shell-Skripten?

17

Sorry, wenn das eine blöde Frage ist, aber ich habe erfolglos danach gesucht.

Was genau macht die zweite Zeile?

#!/bin/sh
cd ${0%/*} || exit 1

Ich weiß, der erste ist der Schebang, der zweite versucht, das Verzeichnis zu wechseln, aber der verwirrende Teil ist ${0%/*}.

Können Sie mir bitte diese zweite Zeile erklären?

Navaro
quelle
2
Wie Andrea in einer Antwort erklärte, wird $ {0% / *} in den Verzeichnispfad übersetzt, der beim Aufrufen des Skripts dem Skriptnamen vorangestellt wird. Eine Alternative ist, den eingebauten dirnameBefehl wie folgt zu verwenden$(dirname $0)
alwayslearning
@alwayslearning: Welche Shell und Shell-Version verwenden Sie, die dirnameeingebaut ist? Es ist sicherlich nicht in Bash v4.3.11, welches die Standard-Shell in Ubuntu Trusty ist.
David Foerster
Ich entschuldige mich für die Verwirrung, habe nur überprüft, dass dirnamees sich nicht um eine eingebaute Shell handelt.
Immer lernen

Antworten:

27

${0}ist das erste Argument des Skripts, dh der Name oder Pfad des Skripts. Wenn Sie Ihr Skript starten wie path/to/script.sh, dann ${0}wird genau diese Zeichenfolge: path/to/script.sh.

Das %/*Teil ändert den Wert von ${0}. Es bedeutet: Nehmen Sie alle Zeichen, bis /ein Dateiname folgt. Im obigen Beispiel ${0%/*}wird sein path/to.

Sie können es in Aktion auf Ihrer Shell sehen:

$ x=path/to/script.sh
$ echo "${x%/*}"
path/to

Sh unterstützt viele andere Arten der "Parametersubstitution". So nehmen Sie beispielsweise den Dateinamen anstelle des Pfads:

$ echo "${x##*/}"
script.sh

Im Allgemeinen %und %%Strip-Suffixe, während #und ##Strip-Präfixe. Sie können mehr über die Parametersubstitution lesen .

Andrea Corbellini
quelle
2
Dieser "|| exit 1" scheint unnötig zu sein: ob es heutzutage sein wird, dir $ zu ändern? entspricht 1.
Josef Klimuk
2
Es wäre schön zu erwähnen, dass das Konstrukt im Handbuch als "Übereinstimmendes Präfix- / Suffixmuster entfernen" dokumentiert ist. Eine gute Möglichkeit, sich zu erinnern, ist, dass # ( links von $) und% ( rechts von $) ist, zumindest auf der US-Tastatur.
chexum
1
@JosefKlimuk: Das wird || exit 1 möglicherweise benötigt, da cdes bei einem Fehler mit Status 2 und nicht mit 1 beendet werden kann. Ich stimme jedoch zu, dass es nicht sehr nützlich ist (normalerweise interessieren sich Programme nicht für bestimmte Exit-Status). Wahrscheinlich ist dies Teil eines größeren Skripts?
Andrea Corbellini
1
@ Andrea Corbellini Sicherlich richtig. Es kann praktisch nur als Teil eines größeren Skripts verwendet werden. Ein Skript, das nur das aktuelle Verzeichnis ändert, hat keine Auswirkung, da es nur die Shell betrifft, die dieses eine Skript ausführt. Der übergeordnete Prozess sieht es nie.
HDV