und die Variante, die ich verwende, um das übergeordnete Arbeitsverzeichnis parentdir=$(dirname `pwd`)
abzurufen
3
Beachten Sie, dass diese Methode für "hässliche" Namen unsicher ist. Ein Name wie "-rm -rf" unterbricht das gewünschte Verhalten. Wahrscheinlich "." wird auch. Ich weiß nicht, ob das der beste Weg ist, aber ich habe hier eine separate "auf Korrektheit ausgerichtete" Frage erstellt: stackoverflow.com/questions/40700119/…
VasiliNovikov
4
@Christopher Shroba Ja, ich habe die Anführungszeichen weggelassen und dann wurde meine Festplatte teilweise gelöscht. Ich erinnere mich nicht genau, was passiert ist: Vermutlich hat ein nicht zitiertes Whitespaced-Verzeichnis das übergeordnete Verzeichnis anstelle des Zielverzeichnisses gelöscht - mein Skript hat gerade den Ordner / home / xxx / gelöscht.
Katamphetamin
3
Oh, okay, es gibt also nichts an dem Befehl, was dazu führen könnte, dass Daten verloren gehen, es sei denn, Sie geben bereits einen Löschbefehl aus, oder? Es war nur eine Frage des Pfades, den Sie entfernen wollten, um sich von einem Leerzeichen trennen zu lassen und viel mehr als erwartet zu entfernen?
Christopher Shroba
18
... aber was " hier gesehen " ist kaputt. Hier ist das Update:
Verwenden Sie einfach, echo $(cd ../ && pwd)während Sie in dem Verzeichnis arbeiten, dessen übergeordnetes Verzeichnis Sie herausfinden möchten. Diese Kette hat auch den zusätzlichen Vorteil, dass sie keine nachlaufenden Schrägstriche aufweist.
Die Verwendung evalist NICHT großartig, wenn die Möglichkeit besteht, Benutzereingaben zu analysieren, die Sie an einen Ort bringen könnten, an dem Sie keine schlechten Dinge erwarten oder gegen Ihr System ausführen. Können Sie pushd $dir 2>&1 >/dev/null && pwd && popd 2>&1 >/dev/nullanstelle der verwenden eval?
Dragon788
2
Sie brauchen evalüberhaupt nicht: tun Sie es einfach parentdir=$(cd -- "$dir" && pwd). Da das cdin einer Subshell ausgeführt wird, müssen Sie nicht dorthin zurückkehren, cdwo wir waren. Das --ist hier für den Fall, dass die Erweiterung von $dirmit einem Bindestrich beginnt. Das &&soll nur verhindern parentdir, dass ein nicht leerer Inhalt vorhanden ist, wenn der cdnicht erfolgreich war.
gniourf_gniourf
8
Motivation für eine andere Antwort
Ich mag sehr kurzen, klaren, garantierten Code. Bonuspunkt, wenn kein externes Programm ausgeführt wird, da es an dem Tag, an dem Sie eine große Anzahl von Einträgen verarbeiten müssen, spürbar schneller ist.
Prinzip
Ich bin mir nicht sicher, welche Garantien Sie haben und wollen, also bieten Sie es trotzdem an.
Wenn Sie Garantien haben, können Sie dies mit sehr kurzem Code tun. Die Idee ist, die Bash-Textersetzungsfunktion zu verwenden, um den letzten Schrägstrich und was auch immer folgt, zu schneiden.
Beantworten Sie einfache bis komplexere Fälle der ursprünglichen Frage.
Wenn der Pfad garantiert ohne Schrägstrich endet (rein und raus)
Wenn der Eingabepfad möglicherweise mit null oder einem Schrägstrich (nicht mehr) endet und der Ausgabepfad ohne Schrägstrich enden soll
for P in \
/home/smith/Desktop/Test \
/home/smith/Desktop/Test/do
P_ENDNOSLASH="${P%/}"; echo "${P_ENDNOSLASH%/*}"done/home/smith/Desktop/home/smith/Desktop
Wenn der Eingabepfad möglicherweise viele externe Schrägstriche enthält und der Ausgabepfad ohne Schrägstrich enden soll
for P in \
/home/smith/Desktop/Test \
/home/smith/Desktop/Test/ \
/home/smith///Desktop////Test//do
P_NODUPSLASH="${P//\/*(\/)/\/}"
P_ENDNOSLASH="${P_NODUPSLASH%%/}"
echo "${P_ENDNOSLASH%/*}";done/home/smith/Desktop/home/smith/Desktop/home/smith/Desktop
Fantastische Antwort. Da es so aussieht, als hätte er nach einer Möglichkeit gesucht, dies innerhalb eines Skripts zu tun (suchen Sie das aktuelle Verzeichnis des Skripts und dessen übergeordnetes Element und tun Sie etwas in Bezug auf den Standort des Skripts), ist dies eine großartige Antwort, und Sie können noch mehr Kontrolle darüber haben, ob Die Eingabe hat einen abschließenden Schrägstrich oder nicht, indem die Parametererweiterung verwendet wird. Dies ${BASH_SOURCE[0]}wäre der vollständige Pfad zum Skript, wenn es nicht über sourceoder bezogen würde ..
Dragon788
7
Wenn /home/smith/Desktop/Test/../es das ist, was Sie wollen:
Entschuldigung, ich meine, wie ein Bash-Skript habe ich eine Variable mit dem Dateipfad
YTKColumba
Das Ausführen dieses Codes gibt mir den Fehler bash: dirname 'Test': syntax error: invalid arithmetic operator (error token is "'Test'"). Verknüpfter Code ist auch falsch.
Michael Hoffman
versuchen Sie einfach dirname Testaus dem Verzeichnis zu laufen Testist in.
Jon Egeland
1
Je nachdem, ob Sie absolute Pfade benötigen, möchten Sie möglicherweise einen zusätzlichen Schritt ausführen:
local lookFor_ parent_ switch_ i_
lookFor_="$1"#if it is not a file, we need the grand parent[-f "$lookFor_"]|| switch_="/.."#length of search string
i_="${#lookFor_}"#remove string one by one until it make sens for the systemwhile["$i_"-ge 0]&&[!-d "${lookFor_:0:$i_}"];do
let i_--done#get real path
parent_="$(realpath "${lookFor_:0:$i_}$switch_")"#done
echo "
lookFor_: $1
{lookFor_:0:$i_}: ${lookFor_:0:$i_}
realpath {lookFor_:0:$i_}: $(realpath ${lookFor_:0:$i_})
parent_: $parent_
"
Wenn Sie aus irgendeinem Grund daran interessiert sind, durch eine bestimmte Anzahl von Verzeichnissen zu navigieren, können Sie auch Folgendes tun : nth_path=$(cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && cd ../../../ && pwd). Dies würde 3 Elternverzeichnisse aufgeben
..
' verwenden, aber vielleicht ist das nicht ganz das, was Sie sich vorgestellt haben.Antworten:
Funktioniert auch, wenn es einen abschließenden Schrägstrich gibt.
quelle
parentdir=$(dirname `pwd`)
... aber was " hier gesehen " ist kaputt. Hier ist das Update:
quelle
Verwenden Sie einfach,
echo $(cd ../ && pwd)
während Sie in dem Verzeichnis arbeiten, dessen übergeordnetes Verzeichnis Sie herausfinden möchten. Diese Kette hat auch den zusätzlichen Vorteil, dass sie keine nachlaufenden Schrägstriche aufweist.quelle
echo
hier nicht.Das übergeordnete Verzeichnis wird eindeutig durch einfaches Anhängen des Punkt-Punkt-Dateinamens angegeben:
Sie müssen jedoch den aufgelösten Pfad (einen absoluten Pfad ohne Punkt-Punkt-Pfad-Komponenten) möchten :
Das Problem mit den häufigsten Antworten
dirname
ist, dass sie nicht funktionieren, wenn Sie einen Pfad mit Punktpunkten eingeben:Das ist mächtiger :
Sie können es füttern
/home/smith/Desktop/Test/..
, aber auch komplexere Pfade wie:BEARBEITEN: Wenn es nicht funktioniert, überprüfen Sie, ob Sie
cd
nicht geändert wurden, wie es manchmal üblich ist.quelle
eval
ist NICHT großartig, wenn die Möglichkeit besteht, Benutzereingaben zu analysieren, die Sie an einen Ort bringen könnten, an dem Sie keine schlechten Dinge erwarten oder gegen Ihr System ausführen. Können Siepushd $dir 2>&1 >/dev/null && pwd && popd 2>&1 >/dev/null
anstelle der verwendeneval
?eval
überhaupt nicht: tun Sie es einfachparentdir=$(cd -- "$dir" && pwd)
. Da dascd
in einer Subshell ausgeführt wird, müssen Sie nicht dorthin zurückkehren,cd
wo wir waren. Das--
ist hier für den Fall, dass die Erweiterung von$dir
mit einem Bindestrich beginnt. Das&&
soll nur verhindernparentdir
, dass ein nicht leerer Inhalt vorhanden ist, wenn dercd
nicht erfolgreich war.Motivation für eine andere Antwort
Ich mag sehr kurzen, klaren, garantierten Code. Bonuspunkt, wenn kein externes Programm ausgeführt wird, da es an dem Tag, an dem Sie eine große Anzahl von Einträgen verarbeiten müssen, spürbar schneller ist.
Prinzip
Ich bin mir nicht sicher, welche Garantien Sie haben und wollen, also bieten Sie es trotzdem an.
Wenn Sie Garantien haben, können Sie dies mit sehr kurzem Code tun. Die Idee ist, die Bash-Textersetzungsfunktion zu verwenden, um den letzten Schrägstrich und was auch immer folgt, zu schneiden.
Beantworten Sie einfache bis komplexere Fälle der ursprünglichen Frage.
Wenn der Pfad garantiert ohne Schrägstrich endet (rein und raus)
Wenn der Pfad garantiert mit genau einem Schrägstrich endet (rein und raus)
Wenn der Eingabepfad möglicherweise mit null oder einem Schrägstrich (nicht mehr) endet und der Ausgabepfad ohne Schrägstrich enden soll
Wenn der Eingabepfad möglicherweise viele externe Schrägstriche enthält und der Ausgabepfad ohne Schrägstrich enden soll
quelle
${BASH_SOURCE[0]}
wäre der vollständige Pfad zum Skript, wenn es nicht übersource
oder bezogen würde.
.Wenn
/home/smith/Desktop/Test/../
es das ist, was Sie wollen:wie hier gesehen .
quelle
bash: dirname 'Test': syntax error: invalid arithmetic operator (error token is "'Test'")
. Verknüpfter Code ist auch falsch.dirname Test
aus dem Verzeichnis zu laufenTest
ist in.Je nachdem, ob Sie absolute Pfade benötigen, möchten Sie möglicherweise einen zusätzlichen Schritt ausführen:
quelle
Verwenden Sie dies:
export MYVAR="$(dirname "$(dirname "$(dirname "$(dirname $PWD)")")")"
Wenn Sie das 4. übergeordnete Verzeichnis möchtenexport MYVAR="$(dirname "$(dirname "$(dirname $PWD)")")"
Wenn Sie das 3. übergeordnete Verzeichnis möchtenexport MYVAR="$(dirname "$(dirname $PWD)")"
Wenn Sie das 2. übergeordnete Verzeichnis möchtenquelle
hässlich aber effizient
{
}}
quelle
Ausgehend von der Idee / dem Kommentar Charles Duffy - 17. Dezember 14 um 5:32 Uhr zum Thema Aktuellen Verzeichnisnamen (ohne vollständigen Pfad) in einem Bash-Skript abrufen
quelle
Wenn Sie aus irgendeinem Grund daran interessiert sind, durch eine bestimmte Anzahl von Verzeichnissen zu navigieren, können Sie auch Folgendes tun :
nth_path=$(cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && cd ../../../ && pwd)
. Dies würde 3 Elternverzeichnisse aufgebenquelle