Wie erhalte ich beim Schreiben eines Bash-Skripts den absoluten Pfad des Speicherorts der aktuellen Datei?

15

Angenommen, ich habe eine Bash-Datei namens myBash.bash. Es befindet sich in:

/myDirect/myFolder/myBash.bash

Jetzt möchte ich die Zeichenfolge /myDirect/myFolder(die Position von myBash.bash) im Skript verwenden. Gibt es einen Befehl, mit dem ich diesen Ort finden kann?

Bearbeiten: Die Idee ist, dass ich einen Zip-Ordner mit Code einrichten möchte, der von einem Bash-Skript in dieser Zip-Datei gestartet werden kann. Ich kenne die relativen Dateipfade des Codes in dieser Zip-Datei, aber nicht die absoluten Pfade, und ich brauche diese. Eine Möglichkeit wäre, den Pfad fest zu codieren oder den Pfad der Datei als Variable anzugeben. Ich würde es jedoch einfacher finden, wenn es der Bash-Datei möglich wäre, herauszufinden, wo sie sich selbst befindet, und dann die relevanten Pfade zur anderen Datei aus ihrem Wissen über die Struktur der Zip-Datei zu erstellen.

dimpol
quelle
3
Dies ist möglicherweise besser für den Stapelüberlauf geeignet. Überprüfen Sie diese Fragen: stackoverflow.com/questions/4774054/… stackoverflow.com/questions/59895/… .
Sethos II
1
benutze wie.? Bitte klären Sie
Sergiy Kolodyazhnyy
1
@ SethosII diese Frage ist hier total zum Thema
Zanna
1
Ich habe der Frage mehr Kontext hinzugefügt. Ich dachte, es könnte einen einfachen / offensichtlichen Befehl geben, um den Dateipfad der Datei abzurufen, die ausgeführt wird, aber es scheint, dass die Antwort zumindest nicht offensichtlich ist.
Dimpol
3
@Zanna Ich sage nicht, dass es offtopisch ist, ich denke, es ist nur angemessener und wie mit den Links gezeigt, die dort bereits mehrmals gefragt und beantwortet wurden.
Sethos II

Antworten:

23

Sie können den vollständigen Pfad wie folgt erhalten:

realpath "$0"

Und wie Serg betont hat, können Sie dirnameden Dateinamen so entfernen

dirname "$(realpath $0)"

oder noch besser, um umständliches Zitieren und Aufteilen von Wörtern mit schwierigen Dateinamen zu vermeiden:

temp=$( realpath "$0"  ) && dirname "$temp"

Viel besser als meine frühere Idee, es zu analysieren (ich wusste, dass es einen besseren Weg geben würde!)

realpath "$0" | sed 's|\(.*\)/.*|\1|'

Anmerkungen

  • realpath Gibt den tatsächlichen Pfad einer Datei zurück
  • $0 ist diese Datei (das Skript)
  • s|old|new|ersetzen olddurchnew
  • \(.*\)/Speichern Sie alle Zeichen vorher /für später
  • \1 das gespeicherte Teil
Zanna
quelle
2
+1 für Gebrauch $0und sedMagie. Aber die besagte sedMagie ist wirklich unnötig, wenn Werkzeuge wie dirnameexistieren
Sergiy Kolodyazhnyy
2
Sie haben bereits die Antwort, verwenden Sie realpath: realpath "$( dirname $0 )"Ich persönlich würde verwenden, readlinkaber das bin ich:readlink -e $(dirname $0)
Sergiy Kolodyazhnyy
@Serg: Wäre nicht dirname "$(realpath "$0")"besser? Normalerweise möchte man das übergeordnete Verzeichnis der referenzierten Datei anstelle des übergeordneten Verzeichnisses des symbolischen Links kennen, der auf diese Datei verweist.
David Foerster
4
@Serg "$(dirname "$(realpath "$0")")"ist der einfachste Weg. Zitate im Inneren $()funktionieren wie gewohnt.
DepressedDaniel
@DepressedDaniel Sie haben ein bisschen online recherchiert, Sie haben Recht: $()Wenn Sie eine Subshell sind, können Sie Zitate im Freien haben. Ich würde nicht sagen, dass es so einfach ist, es sei denn, man merkt, dass $()alle Unterschalen sind
Sergiy Kolodyazhnyy
5

Wenn sich das Skript in Ihrem Pfad befindet, können Sie so etwas wie verwenden

$ myloc=$(dirname "$(which foo.sh)")
$ echo "$myloc"
/path/to/foo.sh

BEARBEITEN: Nach dem Lesen von Kommentaren von Serg kann dies eine generische Lösung sein, die funktioniert, unabhängig davon, ob sich das Skript in Ihrem Pfad befindet oder nicht.

myloc==$(dirname "$(realpath $0)")
dirname "$myloc"
Antonello Piemont
quelle
whichist besser geeignet, wenn sich das Skript in einem der Verzeichnisse befindet, die Teil der PATHVariablen sind. Verwenden Sie es $0aus einem Skript heraus, genau wie Zanna es zeigt. Aber Ihre Antwort ist richtig, da Sie verwenden, dirnameanstatt sich damit zu beschäftigen sed, daher +1 dafür
Sergiy Kolodyazhnyy
5

Die akzeptierte Antwort scheint perfekt zu sein. Hier ist eine andere Möglichkeit:

cd "$(dirname "$0")"
/bin/pwd

/bin/pwdpwdGibt den tatsächlichen Pfad des Verzeichnisses im Gegensatz zum integrierten Befehl aus.

serv-inc
quelle
0
wdir="$PWD"; [ "$PWD" = "/" ] && wdir=""
case "$0" in
  /*) scriptdir="${0}";;
  *) scriptdir="$wdir/${0#./}";;
esac
scriptdir="${scriptdir%/*}"
echo "$scriptdir"

Es wird als Referenz von kenorb und andro verwendet.
Kein dirname, readlink, realpath, BASH_SOURCE
Alle sind eingebaut

HemanthJabalpuri
quelle