Ich habe ein Bash-Skript geschrieben, das eine Eingabedatei als Argument verwendet und liest.
Diese Datei enthält einige Pfade (relativ zu ihrem Speicherort) zu zusätzlichen verwendeten Dateien.
Ich möchte, dass das Skript in den Ordner mit der Eingabedatei wechselt, um weitere Befehle auszuführen.
Also, wie kann ich den Ordner (und nur den Ordner) aus einer Eingabedatei? (Unter Linux.)
Antworten:
Um den vollständigen Pfad zu erhalten, verwenden Sie:
So rufen Sie das Verzeichnis einer Datei ab:
Sie können auch beide kombinieren:
Wenn
readlink -f
es auf Ihrem System nicht verfügbar ist, können Sie Folgendes verwenden * :function myreadlink() { ( cd "$(dirname $1)" # or cd "${1%/*}" echo "$PWD/$(basename $1)" # or echo "$PWD/${1##*/}" ) }
Beachten Sie, dass, wenn Sie nur in ein Verzeichnis einer Datei wechseln müssen, die als relativer Pfad angegeben ist, Sie den absoluten Pfad nicht kennen müssen. Ein relativer Pfad ist vollkommen legal. Verwenden Sie also einfach:
cd $(dirname relative/path/to/file)
Wenn Sie (während das Skript ausgeführt wird) zum ursprünglichen Pfad zurückkehren möchten, verwenden Sie
pushd
anstelle voncd
undpopd
wenn Sie fertig sind.* Während das
myreadlink
oben Gesagte im Zusammenhang mit dieser Frage gut genug ist, weist es einige Einschränkungen in Bezug auf dasreadlink
oben vorgeschlagene Tool auf. Zum Beispiel folgt es nicht richtig einem Link zu einer Datei mit einem anderenbasename
.quelle
readlink -f
dies unter OS X leider nicht funktioniert.brew install coreutils
es bekommen. stackoverflow.com/a/4031502/1022967 .${1%/*}
oder${1##*/}
als Ersatz fürdirname
und zu verwendenbasename
. Die erste Unterbrechung, wenn Sie ihm einen einfachen Dateinamen geben (dirname foo.bar
wäre richtig, wäre.
), und die zweite Unterbrechung für ein Verzeichnis, das mit einem Schrägstrich endet (basename /foo/bar/
, wäre richtig, wärebar
).basename
/dirname
sind nicht Einbauten), und sie werden es auf den ersten Arbeiten sehen , aber scheinbar ohne das Gute in der Zukunft irgendwann plötzlich brechen Grund. Ich würde es vermeiden, es als Option vorzuschlagen, oder ablehnen, dass es nicht wirklich ein kugelsicherer Verdächtiger ist.Werfen Sie einen Blick auf die Manpage für
realpath
, ich benutze das und so etwas wie:zu tun, wie es sich anhört, als würden Sie versuchen zu tun.
quelle
Dies funktioniert sowohl für Dateien als auch für Ordner:
absPath(){ if [[ -d "$1" ]]; then cd "$1" echo "$(pwd -P)" else cd "$(dirname "$1")" echo "$(pwd -P)/$(basename "$1")" fi }
quelle
$cat abs.sh #!/bin/bash echo "$(cd "$(dirname "$1")"; pwd -P)"
Einige Erklärungen:
"$1"
dirname "$1"
cd "$(dirname "$1");
in dieses relative Verzeichnispwd -P
und absoluten Weg bekommen. Die-P
Option vermeidet Symlinksecho
es geschafftFühren Sie dann Ihr Skript aus:
quelle
Probieren Sie unser neues Bash-Bibliotheksprodukt realpath-lib bei GitHub aus, das wir der Community kostenlos und unbeschwert zur Verfügung gestellt haben. Es ist sauber, einfach und gut dokumentiert, daher ist es großartig, daraus zu lernen. Du kannst tun:
get_realpath <absolute|relative|symlink|local file path>
Diese Funktion ist der Kern der Bibliothek:
if [[ -f "$1" ]] then # file *must* exist if cd "$(echo "${1%/*}")" &>/dev/null then # file *may* not be local # exception is ./file.ext # try 'cd .; cd -;' *works!* local tmppwd="$PWD" cd - &>/dev/null else # file *must* be local local tmppwd="$PWD" fi else # file *cannot* exist return 1 # failure fi # reassemble realpath echo "$tmppwd"/"${1##*/}" return 0 # success }
Es ist Bash 4+, erfordert keine Abhängigkeiten und bietet außerdem get_dirname, get_filename, get_stemname und validate_path.
quelle
Das Problem mit der obigen Antwort tritt bei Dateien auf, die mit "./" wie "./my-file.txt" eingegeben wurden.
Problemumgehung (von vielen):
myfile="./somefile.txt" FOLDER="$(dirname $(readlink -f "${ARG}"))" echo ${FOLDER}
quelle
Ich habe readlink -f verwendet und funktioniert unter Linux
damit
FULL_PATH=$(readlink -f filename) DIR=$(dirname $FULL_PATH) PWD=$(pwd) cd $DIR #<do more work> cd $PWD
quelle
PWD
bereits in Bash vorhanden ist und ihr Wert tatsächlich das aktuelle Verzeichnis ist? Und verwenden Sie auch mehr Anführungszeichen.