Antworten:
Sie können das readlink
Dienstprogramm mit der folgenden -f
Option verwenden:
-f, --canonicalize
canonicalize by following every symlink in every component of the given name recursively; all but the last component must exist
Einige Distributionen, zum Beispiel diejenigen, die GNU coreutils und FreeBSD verwenden , enthalten auch ein realpath(1)
Hilfsprogramm, das im Grunde nur aufruft realpath(3)
und so ziemlich dasselbe tut.
readlink
noch realpath
- Solaris und HP-UX, insbesondere.
brew install coreutils
apple.stackexchange.com/a/69332/23040 . Wenn Sie nicht den Schritt ausführen möchten, der alle Standard-Mac-CLI-Tools zu den neu installierten GNU-Entsprechungen umleitet, rufen Sie einfach an greadlink
.
Portabelerweise wird die PWD
Variable von der Shell auf einen absoluten Ort des aktuellen Verzeichnisses gesetzt. Jede Komponente dieses Pfades kann eine symbolische Verknüpfung sein.
case $f in
/*) absolute=$f;;
*) absolute=$PWD/$f;;
esac
Wenn Sie beseitigen wollen .
und ..
auch in das Verzeichnis ändern , um die Datei enthält , und erhalten $PWD
dort:
if [ -d "$f" ]; then f=$f/.; fi
absolute=$(cd "$(dirname -- "$f")"; printf %s. "$PWD")
absolute=${absolute%?}
absolute=$absolute/${f##*/}
Es gibt keine tragbare Möglichkeit, symbolischen Links zu folgen. Wenn Sie einen Pfad zu einem Verzeichnis haben, stellen Sie auf den meisten Unices $(cd -- "$dir" && pwd -P 2>/dev/null || pwd)
einen Pfad bereit, der keine symbolischen Verknüpfungen verwendet, da Shells, die symbolische Verknüpfungen verfolgen, in der Regel implementiert werden pwd -P
("P" für "physisch").
Einige Unices bieten ein Dienstprogramm zum Drucken des „physischen“ Pfads zu einer Datei an.
readlink -f
ebenso wie FreeBSD ≥8.3, NetBSD ≥4.0 und OpenBSD bereits 2.2.realpath
(es ist auch auf einigen Linux-Systemen vorhanden, und es ist in BusyBox).Wenn Perl verfügbar ist, können Sie das Cwd
Modul verwenden .
perl -MCwd -e 'print Cwd::realpath($ARGV[0])' path/to/file
pwd
( $(cd -- "$dir" && pwd -P 2>/dev/null | pwd)
)? Es scheint sich nicht um Stdin zu kümmern.
||
Ist pwd
fit für Ihre Bedürfnisse? Es gibt den absoluten Pfad des aktuellen Verzeichnisses an. Oder vielleicht möchten Sie realpath () .
alister
und rss67
in diesem Artikel stellen wir den stabilsten, kompatibelsten und einfachsten Weg vor. Ich habe noch nie einen besseren Weg als diesen gesehen.
RELPATH=./../
cd $RELPATH
ABSPATH=`pwd`
Wenn Sie zum ursprünglichen Speicherort zurückkehren möchten,
ORGPATH=`pwd`
RELPATH=./../
cd $RELPATH
ABSPATH=`pwd`
cd $ORGPATH
oder
RELPATH=./../
cd $RELPATH
ABSPATH=`pwd`
cd -
Ich wünschte, das hilft. Dies war die beste Lösung für mich.
ABSPATH=$(cd -- "$RELPATH" && pwd)
. Beachten Sie die doppelten Anführungszeichen um die Ersetzung (um nicht zu brechen, wenn der Pfad Leerzeichen und glühende Zeichen enthält) und --
(falls der Pfad mit beginnt -
). Dies funktioniert auch nur für Verzeichnisse und kanonisiert symbolische Links nicht wie gewünscht. Siehe meine Antwort für weitere Details.
Die anderen Antworten hier waren in Ordnung, aber für meine Bedürfnisse nicht ausreichend. Ich brauchte eine Lösung, die ich in meinen Skripten auf jedem Computer verwenden konnte. Meine Lösung bestand darin, ein Shell-Skript zu schreiben, das ich von den Skripten aus aufrufen kann, wo ich es brauche.
#!/bin/sh
if [ $# -eq 0 ] || [ $# -gt 2 ]; then
printf 'Usage: respath path [working-directory]\n' >&2
exit 1
fi
cantGoUp=
path=$1
if [ $# -gt 1 ]; then
cd "$2"
fi
cwd=`pwd -P` #Use -P option to account for directories that are actually symlinks
#Handle non-relative paths, which don't need resolution
if echo "$path" | grep '^/' > /dev/null ; then
printf '%s\n' "$path"
exit 0
fi
#Resolve for each occurrence of ".." at the beginning of the given path.
#For performance, don't worry about ".." in the middle of the path.
while true
do
case "$path" in
..*)
if [ "$cwd" = '/' ]; then
printf 'Invalid relative path\n' >&2
exit 1
fi
if [ "$path" = '..' ]; then
path=
else
path=`echo "$path" | sed 's;^\.\./;;'`
fi
cwd=`dirname $cwd`
;;
*)
break
;;
esac
done
cwd=`echo "$cwd" | sed 's;/$;;'`
if [ -z "$path" ]; then
if [ -z "$cwd" ]; then
cwd='/'
fi
printf '%s\n' "$cwd"
else
printf '%s/%s\n' "$cwd" "$path"
fi
Diese Lösung wurde für die Bourne-Shell entwickelt, um die Portabilität zu gewährleisten. Ich habe dies in einem Skript namens "respath.sh".
Dieses Skript kann folgendermaßen verwendet werden:
respath.sh '/path/to/file'
Oder so
respath.sh '/relative/path/here' '/path/to/resolve/relative/to'
Das Skript löst den Pfad im ersten Argument auf, wobei der Pfad aus dem zweiten Argument als Ausgangspunkt verwendet wird. Wenn nur das erste Argument angegeben wird, löst das Skript den Pfad relativ zu Ihrem aktuellen Arbeitsverzeichnis auf.
pwd
eingebaut und wird nicht unterstützt -P
(die Bourne-Shell hat diese logische $ PWD-Behandlung nicht implementiert, wie dies bei POSIX-Shells der Fall ist ).
cd -P --
wenn das 1. Argument einige enthält ..
case
Scheck sollte ..|../*)
statt ..*
.
dirname $cwd
Falls Sie zusätzlich einen vordefinierten Pfad für $1
(normalerweise ${PWD}
) haben, würde Folgendes funktionieren:
CWD="${1:-${PredefinedAbsolutePath}}"
if [ "${CWD}" != "${PredefinedAbsolutePath}}" ]; then
case $1 in
/*) echo "CWD=${CWD}"; ;;
*) CWD=$(realpath $1); echo "CWD=${CWD}"; ;;
esac
fi
Ich respektiere alle anderen Antworten und fand, dass die folgende Funktion zwischen Linux / MAC OSX sehr einfach und portabel ist als andere, die ich überall gefunden habe. Könnte jemandem helfen.
#!/usr/bin/bash
get_absolute_path(){
file_path=`pwd $1`
echo "$file_path/$1"
}
#to assign to a variable
absolute_path=$(get_absolute_path "file.txt")
echo $absolute_path
Angenommen, die Variable a speichert einen Pfadnamen (a = "whatever").
1. Für einen möglichen raumhaltigen Pfad:
c=$(grep -o " " <<< $a | wc -l); if (( $c > "0" )); then a=$(sed 's/ /\\ /g' <<< $a); fi
2. Für die eigentliche Frage, dh Konvertieren des Pfads in Absolut: readlink kann Symlink-Inhalte abrufen, die wie folgt verwendet werden können. (Anmerkung readlink -f
wäre perfekt gewesen, ist aber nicht in mindestens Mac OS X bash verfügbar, in dem -f für FORMATE steht .)
if [[ $(readlink $a) == "" ]]; then a=$(cd $a; pwd); else a=$(cd $(readlink $a); pwd); fi
3. Soeben erlernt pwd -P
in man pwd
: -P ist das " Anzeigen des physischen aktuellen Arbeitsverzeichnisses (alle symbolischen Verknüpfungen aufgelöst) " und damit
if (( $(grep -o " " <<< $a | wc -l) > "0" )); then a=$(sed 's/ /\\ /g' <<< $a); fi; a=$(cd $a; pwd -P)
soll auch funktionieren.
Fazit: Kombinieren Sie 1 mit 2 , um beide Anforderungen zu erfüllen, während platzhaltende Pfadnamen in der übersichtlicheren Version 3 bereits berücksichtigt sind .
-f
Switch existiert nicht unter Mac OS X (mindestens ab 10.8.5). Ohne den-f
Schalter wird nur ein Fehlercode zurückgegeben.