771 Stimmen

Wie erkenne ich den Namen der Skriptdatei in einem Bash-Skript?

Wie kann ich den Namen der Bash-Skriptdatei im Skript selbst ermitteln?

Wenn mein Skript zum Beispiel in der Datei runme.sh Wie kann ich dann dafür sorgen, dass die Meldung "Sie führen runme.sh aus" angezeigt wird, ohne dies fest zu kodieren?

3 Stimmen

Ähnlich [Kann ein Bash-Skript sagen, in welchem Verzeichnis es gespeichert ist?](zu stackoverflow.com/questions/59895/ )

1 Stimmen

34voto

Mr. Muskrat Punkte 21333

Wenn Sie es ohne den Pfad haben wollen, verwenden Sie ${0##*/}

0 Stimmen

Und was, wenn ich sie ohne optionale Dateierweiterung haben möchte?

0 Stimmen

Um eine Erweiterung zu entfernen, können Sie "${VARIABLE%.ext}" versuchen, wobei VARIABLE der Wert ist, den Sie von ${0##*/} erhalten haben, und ".ext" die Erweiterung ist, die Sie entfernen möchten.

23voto

Travis B. Hartwell Punkte 3141

Zur Antwort Chris Conway unter Linux (zumindest) würden Sie dies tun:

echo $(basename $(readlink -nf $0))

readlink gibt den Wert eines symbolischen Links aus. Wenn es sich nicht um einen symbolischen Link handelt, wird der Dateiname ausgegeben. -n weist es an, keinen Zeilenumbruch auszugeben. -f weist es an, dem Link vollständig zu folgen (wenn ein symbolischer Link ein Link zu einem anderen Link ist, würde er auch diesen auflösen).

2 Stimmen

-n ist harmlos, aber nicht notwendig, da die $(...)-Struktur es abschneiden wird.

21voto

Simon Mattes Punkte 4248

Da in einigen Kommentaren die Frage nach dem Dateinamen ohne Erweiterung gestellt wurde, hier ein Beispiel, wie man das erreichen kann:

FileName=${0##*/}
FileNameWithoutExtension=${FileName%.*}

Viel Spaß!

0 Stimmen

Das ist schwarze Magie!

20voto

gkb0986 Punkte 2749

Ich habe festgestellt, dass diese Zeile immer funktioniert, unabhängig davon, ob die Datei ausgelagert oder als Skript ausgeführt wird.

echo "${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}"

Wenn Sie Symlinks folgen wollen, verwenden Sie readlink auf dem Pfad, den Sie oben erhalten haben, rekursiv oder nicht rekursiv.

Der Grund, warum der Einzeiler funktioniert, liegt in der Verwendung der BASH_SOURCE Umgebungsvariable und die zugehörige FUNCNAME .

BASH_SOURCE

Eine Array-Variable, deren Mitglieder die Namen der Quelldateien sind, in denen die entsprechenden Shell-Funktionsnamen in der Array-Variable FUNCNAME definiert sind. Die Shell-Funktion ${FUNCNAME[$i]} wird in der Datei ${BASH_SOURCE[$i]} definiert und von ${BASH_SOURCE[$i+1]} aufgerufen.

FUNCNAME

Eine Array-Variable, die die Namen aller Shell-Funktionen enthält, die sich derzeit im Aufrufstapel der Ausführung befinden. Das Element mit dem Index 0 ist der Name einer beliebigen derzeit ausgeführten Shell-Funktion. Das unterste Element (das Element mit dem höchsten Index) ist "main". Diese Variable existiert nur, wenn eine Shell-Funktion ausgeführt wird. Zuweisungen an FUNCNAME haben keine Wirkung und geben einen Fehlerstatus zurück. Wenn FUNCNAME nicht gesetzt wird, verliert sie ihre besonderen Eigenschaften, auch wenn sie anschließend zurückgesetzt wird.

Diese Variable kann mit BASH_LINENO und BASH_SOURCE verwendet werden. Jedes Element von FUNCNAME hat entsprechende Elemente in BASH_LINENO und BASH_SOURCE, um den Aufrufstapel zu beschreiben. Zum Beispiel wurde ${FUNCNAME[$i]} aus der Datei ${BASH_SOURCE[$i+1]} in Zeile ${BASH_LINENO[$i]} aufgerufen. Das Caller-Builtin zeigt den aktuellen Aufrufstapel anhand dieser Informationen an.

[Quelle: Bash-Handbuch]

2 Stimmen

Es funktioniert, wenn Sie den Quellcode in der Datei a (angenommen a Der Inhalt von echo "${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}" ) von einer interaktiven Sitzung aus - dann wird es Ihnen a den Weg. Aber wenn Sie ein Skript schreiben b con source a hinein und führen Sie ./b wird er zurückkehren b den Weg.

0 Stimmen

Gibt Ihre Antwort nicht die ERSTE Datei an und nicht die letzte/aktuellste Datei? Ich finde, dass ${BASH_SOURCE[0]}" oder einfach $BASH_SOURCE mir die aktuelle Datei anzeigt - d.h. die Antwort, die @Zainka gepostet hat.

12voto

Jim Dodd Punkte 241

Diese Antworten sind für die angegebenen Fälle korrekt, aber es gibt immer noch ein Problem, wenn Sie das Skript von einem anderen Skript aus mit dem Schlüsselwort "source" ausführen (so dass es in der gleichen Shell läuft). In diesem Fall erhalten Sie die $0 des aufrufenden Skripts. Und in diesem Fall ist es meines Erachtens nicht möglich, den Namen des Skripts selbst zu erfahren.

Dies ist ein Sonderfall und sollte nicht allzu ernst genommen werden. Wenn Sie das Skript direkt von einem anderen Skript aus ausführen (ohne "source"), funktioniert die Verwendung von $0.

2 Stimmen

Sie haben ein sehr gutes Argument. IMO ist das kein Sonderfall. Es gibt jedoch eine Lösung: Siehe Die Antwort von Dimitre Radoulov oben

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X