Unix-Shell-Skript Finden Sie heraus, in welchem Verzeichnis sich die Skriptdatei befindet.
511
Grundsätzlich muss ich das Skript mit Pfaden ausführen, die sich auf den Speicherort der Shell-Skriptdatei beziehen. Wie kann ich das aktuelle Verzeichnis in dasselbe Verzeichnis ändern, in dem sich die Skriptdatei befindet?
Ist das wirklich ein Duplikat? Diese Frage bezieht sich auf ein "Unix-Shell-Skript", die andere speziell auf Bash.
Michaeljt
2
@ BoltClock: Diese Frage wurde nicht ordnungsgemäß geschlossen. Die verknüpfte Frage bezieht sich auf Bash. Diese Frage betrifft die Unix-Shell-Programmierung. Beachten Sie, dass die akzeptierten Antworten sehr unterschiedlich sind!
Dietrich Epp
@Dietrich Epp: Du hast recht. Es scheint, dass die Wahl der akzeptierten Antwort durch den Fragesteller und das Hinzufügen des [bash] -Tags (wahrscheinlich als Antwort darauf) mich dazu veranlasst haben, die Frage als Duplikat als Antwort auf eine Flagge zu markieren.
Dies funktioniert nicht, wenn Sie das Skript über einen symbolischen Link in einem anderen Verzeichnis aufgerufen haben. Damit dies funktioniert, müssen Sie readlinkauch verwenden (siehe Antwort von al unten)
AndrewR
44
In Bash ist es sicherer, $BASH_SOURCEanstelle von zu verwenden $0, da $0es nicht immer den Pfad des aufgerufenen Skripts enthält, z. B. beim "Sourcing" eines Skripts.
mklement0
2
$BASH_SOURCEist Bash-spezifisch, die Frage betrifft das Shell-Skript im Allgemeinen.
Ha-Duong Nguyen
7
@auraham: CUR_PATH=$(pwd)oder pwdgeben Sie das aktuelle Verzeichnis zurück (das nicht das übergeordnete Verzeichnis des Skripts sein muss)!
Andreas Dietrich
5
Ich habe die empfohlene Methode @ mklement0 ausprobiert $BASH_SOURCEund sie gibt das zurück, was ich brauchte. Mein Skript wird von einem anderen Skript aufgerufen und gibt $0zurück, .während $BASH_SOURCEdas richtige Unterverzeichnis (in meinem Fall scripts) zurückgegeben wird.
David Rissato Cruz
401
Der ursprüngliche Beitrag enthält die Lösung (ignorieren Sie die Antworten, sie fügen nichts Nützliches hinzu). Die interessante Arbeit erledigt der erwähnte Unix-Befehl readlinkmit Option -f. Funktioniert, wenn das Skript sowohl von einem absoluten als auch von einem relativen Pfad aufgerufen wird.
Für bash, sh, ksh:
#!/bin/bash # Absolute path to this script, e.g. /home/user/bin/foo.sh
SCRIPT=$(readlink -f "$0")# Absolute path this script is in, thus /home/user/bin
SCRIPTPATH=$(dirname "$SCRIPT")
echo $SCRIPTPATH
Für tcsh gilt csh:
#!/bin/tcsh# Absolute path to this script, e.g. /home/user/bin/foo.cshset SCRIPT=`readlink -f "$0"`# Absolute path this script is in, thus /home/user/binset SCRIPTPATH=`dirname "$SCRIPT"`
echo $SCRIPTPATH
Zur Verdeutlichung des Kommentars von @ Ergwun: Wird unter -fOS X (ab Lion) überhaupt nicht unterstützt. Dort können Sie entweder das ablegen -f, um mit dem Auflösen höchstens einer Indirektionsebene auszukommen, z. B. pushd "$(dirname "$(readlink "$BASH_SOURCE" || echo "$BASH_SOURCE")")"oder Sie können Ihr eigenes rekursives Symlink-Follow-Skript erstellen, wie im verlinkten Beitrag gezeigt.
mklement0
2
Ich verstehe immer noch nicht, warum das OP den absoluten Weg brauchen würde. Berichterstattung "." sollte in Ordnung funktionieren, wenn Sie auf Dateien relativ zum Skriptpfad zugreifen möchten und das Skript wie ./myscript.sh
Stefan Haberl
10
@StefanHaberl Ich denke, es wäre ein Problem, wenn Sie das Skript ausführen würden, während sich Ihr aktuelles Arbeitsverzeichnis vom Speicherort des Skripts unterscheidet (z. B. wäre sh /some/other/directory/script.sh)in diesem Fall .Ihr pwd, nicht/some/other/directory
Jon z
51
Ein früherer Kommentar zu einer Antwort sagte es, aber es ist leicht, unter allen anderen Antworten zu übersehen.
Bei Verwendung von Bash:
echo this file:"$BASH_SOURCE"
echo this dir:"$(dirname "$BASH_SOURCE")"
Nur dieses funktioniert mit einem Skript im Umgebungspfad, die am häufigsten bewerteten funktionieren nicht. Vielen Dank!
Juli
Sie sollten dirname "$BASH_SOURCE"stattdessen Leerzeichen in $ BASH_SOURCE verwenden.
Mygod
1
Eine explizitere Methode zum Drucken des Verzeichnisses wäre laut Tool ShellCheck: "$ (dirname" $ {BASH_SOURCE {0}} ")", da BASH_SOURCE ein Array ist und ohne den Index standardmäßig das erste Element verwendet wird .
Adrian M.
1
@AdrianM. , Sie wollen Klammern, nicht Klammern, für den Index:"$(dirname "${BASH_SOURCE[0]}")"
Hashbrown
Nicht gut für mich ... druckt nur einen Punkt (dh vermutlich das aktuelle Verzeichnis)
Dieses Skript sollte das Verzeichnis drucken, in dem Sie sich befinden, und dann das Verzeichnis, in dem sich das Skript befindet. Wenn Sie es beispielsweise /mit dem Skript aufrufen /home/mez/, wird es ausgegeben
//home/mez
Denken Sie daran, wenn Sie Variablen aus der Ausgabe eines Befehls zuweisen, schließen Sie den Befehl ein $(und )- oder Sie erhalten nicht die gewünschte Ausgabe.
Dies funktioniert nicht, wenn ich das Skript aus dem aktuellen Verzeichnis aufrufe.
Eric Wang
1
@EricWang du bist immer im aktuellen Verzeichnis.
Strg-Alt-Delor
Für mich ist $ current_dir tatsächlich der Pfad, von dem aus ich das Skript aufrufe. $ Script_dir ist jedoch nicht das Verzeichnis des Skripts, sondern nur ein Punkt.
Michael
31
Wenn Sie Bash verwenden ...
#!/bin/bash
pushd $(dirname "${0}")>/dev/null
basedir=$(pwd -L)# Use "pwd -P" for the path without links. man bash for more info.
popd >/dev/null
echo "${basedir}"
Sie können das pushd/ popddurch cd $(dirname "${0}")und ersetzen cd -, damit es auf anderen Shells funktioniert, wenn diese eine haben pwd -L.
docwhat
warum würdest du hier pushd und popd verwenden?
Qodeninja
1
Ich muss das ursprüngliche Verzeichnis also nicht in einer Variablen speichern. Es ist ein Muster, das ich häufig in Funktionen und dergleichen verwende. Es nistet wirklich gut, was gut ist.
docwhat
Es wird immer noch im Speicher gespeichert - in einer Variablen - ob in Ihrem Skript auf eine Variable verwiesen wird oder nicht. Ich glaube auch, dass die Kosten für die Ausführung von pushd und popd die Einsparungen bei weitem nicht überwiegen, wenn in Ihrem Skript keine lokale Bash-Variable erstellt wird, sowohl in Bezug auf die CPU-Zyklen als auch in Bezug auf die Lesbarkeit.
Ingyhere
20
Wie der Marko vorschlägt:
BASEDIR=$(dirname $0)
echo $BASEDIR
Dies funktioniert nur, wenn Sie das Skript in demselben Verzeichnis ausführen, in dem sich das Skript befindet. In diesem Fall erhalten Sie den Wert '.'
Sie können jetzt die Variable current_dir in Ihrem Skript verwenden, um auf das Skriptverzeichnis zu verweisen. Dies kann jedoch immer noch das Symlink-Problem haben.
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}")" && pwd )"
Einzeiler, der Ihnen den vollständigen Verzeichnisnamen des Skripts gibt, unabhängig davon, von wo es aufgerufen wird.
Um zu verstehen, wie es funktioniert, können Sie das folgende Skript ausführen:
#!/bin/bash
SOURCE="${BASH_SOURCE[0]}"while[-h "$SOURCE"];do# resolve $SOURCE until the file is no longer a symlink
TARGET="$(readlink "$SOURCE")"if[[ $TARGET ==/*]];then
echo "SOURCE '$SOURCE' is an absolute symlink to '$TARGET'"
SOURCE="$TARGET"else
DIR="$( dirname "$SOURCE" )"
echo "SOURCE '$SOURCE' is a relative symlink to '$TARGET' (relative to '$DIR')"
SOURCE="$DIR/$TARGET"# if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was locatedfidone
echo "SOURCE is '$SOURCE'"
RDIR="$( dirname "$SOURCE" )"
DIR="$( cd -P "$( dirname "$SOURCE")" && pwd )"if["$DIR"!="$RDIR"];then
echo "DIR '$RDIR' resolves to '$DIR'"fi
echo "DIR is '$DIR'"
@Der_Meister - bitte genauer sein. Oder schreiben (und möglicherweise verschlüsseln) Sie eine E-Mail an jasan unter jasan.tk
Ján Sáreník
2
ln -s / home / der / 1 / test / home / der / 2 / test && / home / der / 2 / test => / home / der / 2 (sollte stattdessen den Pfad zum ursprünglichen Skript
der zuverlässigste nicht-bash-spezifische Weg, den ich kenne.
Eddygeek
9
Wenn Sie das eigentliche Skriptverzeichnis abrufen möchten (unabhängig davon, ob Sie das Skript über einen Symlink oder direkt aufrufen), versuchen Sie Folgendes:
Dies funktioniert sowohl unter Linux als auch unter MacOS. Ich konnte hier niemanden erwähnen sehen realpath. Ich bin mir nicht sicher, ob dieser Ansatz Nachteile aufweist.
Unter MacOS müssen Sie installieren, coreutilsum verwenden zu können realpath. ZB : brew install coreutils.
WARUM FUNKTIONIERT DIE VERWENDUNG DES Dirnamens "$ 0" NICHT?
dirname $ 0 funktioniert nur, wenn der Benutzer das Skript auf eine ganz bestimmte Weise startet. Ich konnte mehrere Situationen finden, in denen diese Antwort fehlschlägt und das Skript zum Absturz bringt.
Lassen Sie uns zunächst verstehen, wie diese Antwort funktioniert. Er bekommt das Skriptverzeichnis, indem er es tut
dirname "$0"
$ 0 stellt den ersten Teil des Befehls dar, der das Skript aufruft (es ist im Grunde der eingegebene Befehl ohne die Argumente:
/some/path/./script argument1 argument2
$ 0 = "/ some / path /./ script"
dirname findet im Grunde das letzte / in einem String und schneidet es dort ab. Wenn Sie dies tun:
dirname /usr/bin/sha256sum
Sie erhalten: / usr / bin
Dieses Beispiel funktioniert gut, da / usr / bin / sha256sum aber ein richtig formatierter Pfad ist
dirname "/some/path/./script"
würde nicht gut funktionieren und würde dir geben:
BASENAME="/some/path/."#which would crash your script if you try to use it as a path
Angenommen, Sie befinden sich im selben Verzeichnis wie Ihr Skript und starten es mit diesem Befehl
./script
$ 0 in dieser Situation ist ./script und dirname $ 0 gibt an:
.#or BASEDIR=".", again this will crash your script
Verwenden von:
sh script
Ohne Eingabe des vollständigen Pfads wird auch ein BASEDIR = "."
Relative Verzeichnisse verwenden:
../some/path/./script
Gibt einen Dirnamen $ 0 von:
../some/path/.
Wenn Sie sich im Verzeichnis / some befinden und das Skript auf diese Weise aufrufen (beachten Sie das Fehlen von / am Anfang, wieder ein relativer Pfad):
path/./script.sh
Sie erhalten diesen Wert für dirname $ 0:
path/.
und ./path/./script (eine andere Form des relativen Pfades) ergibt:
./path/.
Die einzigen zwei Situationen, in denen basedir $ 0 funktioniert, sind, wenn der Benutzer sh oder touch verwendet, um ein Skript zu starten, da beide zu $ 0 führen:
$0=/some/path/script
Dadurch erhalten Sie einen Pfad, den Sie mit dirname verwenden können.
DIE LÖSUNG
Sie müssen jede der oben genannten Situationen berücksichtigen und erkennen und eine Korrektur dafür anwenden, wenn sie auftritt:
#!/bin/bash#this script will only work in bash, make sure it's installed on your system.#set to false to not see all the echos
debug=true
if["$debug"= true ];then echo "\$0=$0";fi#The line below detect script's parent directory. $0 is the part of the launch command that doesn't contain the arguments
BASEDIR=$(dirname "$0")#3 situations will cause dirname $0 to fail: #situation1: user launches script while in script dir ( $0=./script)#situation2: different dir but ./ is used to launch script (ex. $0=/path_to/./script)#situation3: different dir but relative path used to launch scriptif["$debug"= true ];then echo 'BASEDIR=$(dirname "$0") gives: '"$BASEDIR";fiif["$BASEDIR"="."];then BASEDIR="$(pwd)";fi# fix for situation1
_B2=${BASEDIR:$((${#BASEDIR}-2))}; B_=${BASEDIR::1}; B_2=${BASEDIR::2}; B_3=${BASEDIR::3}# <- bash onlyif["$_B2"="/."];then BASEDIR=${BASEDIR::$((${#BASEDIR}-1))};fi#fix for situation2 # <- bash onlyif["$B_"!="/"];then#fix for situation3 #<- bash onlyif["$B_2"="./"];then#covers ./relative_path/(./)scriptif["$(pwd)"!="/"];then BASEDIR="$(pwd)/${BASEDIR:2}";else BASEDIR="/${BASEDIR:2}";fielse#covers relative_path/(./)script and ../relative_path/(./)script, using ../relative_path fails if current path is a symbolic linkif["$(pwd)"!="/"];then BASEDIR="$(pwd)/$BASEDIR";else BASEDIR="/$BASEDIR";fififiif["$debug"= true ];then echo "fixed BASEDIR=$BASEDIR";fi
Dieser Einzeiler gibt an, wo sich das Shell-Skript befindet. Dabei spielt es keine Rolle, ob Sie es ausgeführt haben oder ob Sie es bezogen haben . Außerdem werden alle beteiligten symbolischen Verknüpfungen aufgelöst, wenn dies der Fall ist:
So viele Antworten, alle plausibel, jede mit Vor- und Nachteilen und leicht unterschiedlichen Zielen (die wahrscheinlich für jede angegeben werden sollten). Hier ist eine weitere Lösung, die das Hauptziel erfüllt, klar zu sein und systemübergreifend auf allen Bashs zu arbeiten (keine Annahmen über Bash-Versionen oderreadlink oderpwd -Optionen) und vernünftigerweise das zu tun, was Sie erwarten würden (z. B. das Auflösen von Symlinks ist eine interessantes Problem, aber normalerweise nicht das, was Sie tatsächlich wollen), behandeln Sie Randfälle wie Leerzeichen in Pfaden usw., ignorieren Sie alle Fehler und verwenden Sie einen vernünftigen Standard, wenn es Probleme gibt.
Jede Komponente wird in einer separaten Variablen gespeichert, die Sie einzeln verwenden können:
# script path, filename, directory
PROG_PATH=${BASH_SOURCE[0]}# this script's name
PROG_NAME=${PROG_PATH##*/} # basename of script (strip path)
PROG_DIR="$(cd "$(dirname "${PROG_PATH:-$PWD}")" 2>/dev/null 1>&2 && pwd)"
Es könnte hässlich aussehen, abhängig davon, wie es aufgerufen wurde und wie es mit dem CWD funktioniert, aber es sollte Sie dahin bringen, wo Sie hin müssen (oder Sie können die Zeichenfolge optimieren, wenn Sie sich dafür interessieren, wie sie aussieht).
Antworten:
In Bash sollten Sie das bekommen, was Sie brauchen:
quelle
readlink
auch verwenden (siehe Antwort von al unten)$BASH_SOURCE
anstelle von zu verwenden$0
, da$0
es nicht immer den Pfad des aufgerufenen Skripts enthält, z. B. beim "Sourcing" eines Skripts.$BASH_SOURCE
ist Bash-spezifisch, die Frage betrifft das Shell-Skript im Allgemeinen.CUR_PATH=$(pwd)
oderpwd
geben Sie das aktuelle Verzeichnis zurück (das nicht das übergeordnete Verzeichnis des Skripts sein muss)!$BASH_SOURCE
und sie gibt das zurück, was ich brauchte. Mein Skript wird von einem anderen Skript aufgerufen und gibt$0
zurück,.
während$BASH_SOURCE
das richtige Unterverzeichnis (in meinem Fallscripts
) zurückgegeben wird.Der ursprüngliche Beitrag enthält die Lösung (ignorieren Sie die Antworten, sie fügen nichts Nützliches hinzu). Die interessante Arbeit erledigt der erwähnte Unix-Befehl
readlink
mit Option-f
. Funktioniert, wenn das Skript sowohl von einem absoluten als auch von einem relativen Pfad aufgerufen wird.Für bash, sh, ksh:
Für tcsh gilt csh:
Siehe auch: https://stackoverflow.com/a/246128/59087
quelle
readlink
. Aus diesem Grund habe ich die Verwendung von pushd / popd (integrierte Funktionen für Bash) empfohlen.-f
Option,readlink
unter OS X (Lion) und möglicherweise BSD etwas anderes zu tun. stackoverflow.com/questions/1055671/…-f
OS X (ab Lion) überhaupt nicht unterstützt. Dort können Sie entweder das ablegen-f
, um mit dem Auflösen höchstens einer Indirektionsebene auszukommen, z. B.pushd "$(dirname "$(readlink "$BASH_SOURCE" || echo "$BASH_SOURCE")")"
oder Sie können Ihr eigenes rekursives Symlink-Follow-Skript erstellen, wie im verlinkten Beitrag gezeigt.sh /some/other/directory/script.sh)
in diesem Fall.
Ihr pwd, nicht/some/other/directory
Ein früherer Kommentar zu einer Antwort sagte es, aber es ist leicht, unter allen anderen Antworten zu übersehen.
Bei Verwendung von Bash:
Bash-Referenzhandbuch, 5.2 Bash-Variablen
quelle
dirname "$BASH_SOURCE"
stattdessen Leerzeichen in $ BASH_SOURCE verwenden."$(dirname "${BASH_SOURCE[0]}")"
Angenommen, Sie verwenden Bash
Dieses Skript sollte das Verzeichnis drucken, in dem Sie sich befinden, und dann das Verzeichnis, in dem sich das Skript befindet. Wenn Sie es beispielsweise
/
mit dem Skript aufrufen/home/mez/
, wird es ausgegebenDenken Sie daran, wenn Sie Variablen aus der Ausgabe eines Befehls zuweisen, schließen Sie den Befehl ein
$(
und)
- oder Sie erhalten nicht die gewünschte Ausgabe.quelle
Wenn Sie Bash verwenden ...
quelle
pushd
/popd
durchcd $(dirname "${0}")
und ersetzencd -
, damit es auf anderen Shells funktioniert, wenn diese eine habenpwd -L
.Wie der Marko vorschlägt:
Dies funktioniert nur, wenn Sie das Skript in demselben Verzeichnis ausführen, in dem sich das Skript befindet. In diesem Fall erhalten Sie den Wert '.'
Um dieses Problem zu umgehen, verwenden Sie:
Sie können jetzt die Variable current_dir in Ihrem Skript verwenden, um auf das Skriptverzeichnis zu verweisen. Dies kann jedoch immer noch das Symlink-Problem haben.
quelle
Die beste Antwort auf diese Frage wurde hier beantwortet:
Abrufen des Quellverzeichnisses eines Bash-Skripts von innen
Und es ist:
Einzeiler, der Ihnen den vollständigen Verzeichnisnamen des Skripts gibt, unabhängig davon, von wo es aufgerufen wird.
Um zu verstehen, wie es funktioniert, können Sie das folgende Skript ausführen:
quelle
quelle
Machen wir es zu einem POSIX-Oneliner:
Getestet auf vielen Bourne-kompatiblen Schalen, einschließlich der BSD-Schalen.
Soweit ich weiß, bin ich der Autor und habe es gemeinfrei gemacht. Weitere Informationen finden Sie unter: https://www.jasan.tk/posts/2017-05-11-posix_shell_dirname_replacement/
quelle
cd: too many arguments
wenn Leerzeichen im Pfad, und kehrt zurück$PWD
. (eine offensichtliche Lösung, zeigt aber nur, wie vielequelle
Wenn Sie das eigentliche Skriptverzeichnis abrufen möchten (unabhängig davon, ob Sie das Skript über einen Symlink oder direkt aufrufen), versuchen Sie Folgendes:
Dies funktioniert sowohl unter Linux als auch unter MacOS. Ich konnte hier niemanden erwähnen sehen
realpath
. Ich bin mir nicht sicher, ob dieser Ansatz Nachteile aufweist.Unter MacOS müssen Sie installieren,
coreutils
um verwenden zu könnenrealpath
. ZB :brew install coreutils
.quelle
EINFÜHRUNG
Diese Antwort korrigiert die sehr kaputte, aber schockierend am besten gewählte Antwort dieses Threads (geschrieben von TheMarko):
WARUM FUNKTIONIERT DIE VERWENDUNG DES Dirnamens "$ 0" NICHT?
dirname $ 0 funktioniert nur, wenn der Benutzer das Skript auf eine ganz bestimmte Weise startet. Ich konnte mehrere Situationen finden, in denen diese Antwort fehlschlägt und das Skript zum Absturz bringt.
Lassen Sie uns zunächst verstehen, wie diese Antwort funktioniert. Er bekommt das Skriptverzeichnis, indem er es tut
$ 0 stellt den ersten Teil des Befehls dar, der das Skript aufruft (es ist im Grunde der eingegebene Befehl ohne die Argumente:
$ 0 = "/ some / path /./ script"
dirname findet im Grunde das letzte / in einem String und schneidet es dort ab. Wenn Sie dies tun:
Sie erhalten: / usr / bin
Dieses Beispiel funktioniert gut, da / usr / bin / sha256sum aber ein richtig formatierter Pfad ist
würde nicht gut funktionieren und würde dir geben:
Angenommen, Sie befinden sich im selben Verzeichnis wie Ihr Skript und starten es mit diesem Befehl
$ 0 in dieser Situation ist ./script und dirname $ 0 gibt an:
Verwenden von:
Ohne Eingabe des vollständigen Pfads wird auch ein BASEDIR = "."
Relative Verzeichnisse verwenden:
Gibt einen Dirnamen $ 0 von:
Wenn Sie sich im Verzeichnis / some befinden und das Skript auf diese Weise aufrufen (beachten Sie das Fehlen von / am Anfang, wieder ein relativer Pfad):
Sie erhalten diesen Wert für dirname $ 0:
und ./path/./script (eine andere Form des relativen Pfades) ergibt:
Die einzigen zwei Situationen, in denen basedir $ 0 funktioniert, sind, wenn der Benutzer sh oder touch verwendet, um ein Skript zu starten, da beide zu $ 0 führen:
Dadurch erhalten Sie einen Pfad, den Sie mit dirname verwenden können.
DIE LÖSUNG
Sie müssen jede der oben genannten Situationen berücksichtigen und erkennen und eine Korrektur dafür anwenden, wenn sie auftritt:
quelle
Dieser Einzeiler gibt an, wo sich das Shell-Skript befindet. Dabei spielt es keine Rolle, ob Sie es ausgeführt haben oder ob Sie es bezogen haben . Außerdem werden alle beteiligten symbolischen Verknüpfungen aufgelöst, wenn dies der Fall ist:
Ich nehme an, Sie verwenden / bin / bash .
quelle
So viele Antworten, alle plausibel, jede mit Vor- und Nachteilen und leicht unterschiedlichen Zielen (die wahrscheinlich für jede angegeben werden sollten). Hier ist eine weitere Lösung, die das Hauptziel erfüllt, klar zu sein und systemübergreifend auf allen Bashs zu arbeiten (keine Annahmen über Bash-Versionen oder
readlink
oderpwd
-Optionen) und vernünftigerweise das zu tun, was Sie erwarten würden (z. B. das Auflösen von Symlinks ist eine interessantes Problem, aber normalerweise nicht das, was Sie tatsächlich wollen), behandeln Sie Randfälle wie Leerzeichen in Pfaden usw., ignorieren Sie alle Fehler und verwenden Sie einen vernünftigen Standard, wenn es Probleme gibt.Jede Komponente wird in einer separaten Variablen gespeichert, die Sie einzeln verwenden können:
quelle
Inspiriert von Blueyeds Antwort
quelle
Das sollte den Trick machen:
Es könnte hässlich aussehen, abhängig davon, wie es aufgerufen wurde und wie es mit dem CWD funktioniert, aber es sollte Sie dahin bringen, wo Sie hin müssen (oder Sie können die Zeichenfolge optimieren, wenn Sie sich dafür interessieren, wie sie aussieht).
quelle
`pwd`/`dirname $0`
aber kann immer noch auf Symlinks fehlschlagen