Existuje příkaz Unix k získání absolutní (a kanonické) cesty z relativní cesty, která může obsahovat symbolické odkazy?
Můžete použít nástroj readlink
s možností -f
:
-f, --canonicalize
canonicalize by following every symlink in every component of the given name recursively; all but the last component must exist
Některé distribuce, například ty, které používají GNU coreutils a FreeBSD , také přicházejí s obslužným programem realpath(1)
, který v podstatě pouze volá realpath(3)
a do značné míry to samé.
Přenosná proměnná PWD
je Shell nastavena na jedno absolutní umístění aktuálního adresáře. Jakákoli součást této cesty může být symbolickým odkazem.
case $f in
/*) absolute=$f;;
*) absolute=$PWD/$f;;
esac
Pokud chcete vyloučit také .
A ..
, Přejděte do adresáře obsahujícího soubor a získejte tam $PWD
:
if [ -d "$f" ]; then f=$f/.; fi
absolute=$(cd "$(dirname -- "$f")"; printf %s. "$PWD")
absolute=${absolute%?}
absolute=$absolute/${f##*/}
Neexistuje žádný přenosný způsob, jak sledovat symbolické odkazy. Pokud máte cestu k adresáři, pak ve většině unices $(cd -- "$dir" && pwd -P 2>/dev/null || pwd)
poskytuje cestu, která nepoužívá symbolické odkazy, protože shelly, které sledují symbolické odkazy, mají tendenci implementovat pwd -P
(„P“) pro „fyzické“).
Některé sektory poskytují nástroj pro tisk „fyzické“ cesty k souboru.
readlink -f
, stejně jako FreeBSD ≥ 8.3, NetBSD ≥4,0 a OpenBSD již v 2.2.realpath
(je také přítomen v některých systémech Linux a je v BusyBoxu).Pokud je k dispozici Perl, můžete použít modul Cwd
.
Perl -MCwd -e 'print Cwd::realpath($ARGV[0])' path/to/file
Je pwd
vhodný pro vaše potřeby? Poskytuje absolutní cestu k aktuálnímu adresáři. Nebo to, co chcete, je realpath () .
alister
a rss67
in tento článek představuje nejstabilnější, kompatibilní a nejjednodušší způsob. Nikdy jsem neviděl lepší způsob než tohle.
RELPATH=./../
cd $RELPATH
ABSPATH=`pwd`
Pokud se chcete vrátit na původní místo,
ORGPATH=`pwd`
RELPATH=./../
cd $RELPATH
ABSPATH=`pwd`
cd $ORGPATH
nebo
RELPATH=./../
cd $RELPATH
ABSPATH=`pwd`
cd -
Přál bych si, aby to pomohlo. To bylo pro mě největší řešení.
S ohledem na odpověď všech ostatních jsem zjistil, že níže uvedená funkce je velmi snadná a přenosná mezi linux/MAC OSX než ostatní, které jsem našla všude. Může někomu pomoci.
#!/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
Ostatní odpovědi byly v pořádku, ale nebyly dostatečné pro mé potřeby. Potřeboval jsem řešení, které bych mohl použít ve svých skriptech na jakémkoli počítači. Mým řešením bylo napsat skript Shell, který mohu vyvolat ze skriptů, kde je potřebuji.
#!/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
Toto řešení je psáno pro Bourne Shell pro přenositelnost. Mám to ve skriptu s názvem "respath.sh".
Tento skript lze použít takto:
respath.sh '/path/to/file'
Nebo takhle
respath.sh '/relative/path/here' '/path/to/resolve/relative/to'
Skript vyřeší cestu v prvním argumentu pomocí cesty z druhého argumentu jako výchozího bodu. Pokud je zadán pouze první argument, skript vyřeší cestu relativně k vašemu aktuálnímu pracovnímu adresáři.
V případě, že navíc máte předdefinovanou cestu pro $1
(obvykle ${PWD}
), bude fungovat následující:
CWD="${1:-${PredefinedAbsolutePath}}"
if [ "${CWD}" != "${PredefinedAbsolutePath}}" ]; then
case $1 in
/*) echo "CWD=${CWD}"; ;;
*) CWD=$(realpath $1); echo "CWD=${CWD}"; ;;
esac
fi