Existe-t-il une commande Unix pour obtenir le chemin absolu (et canonisé) à partir d'un chemin relatif qui peut contenir des liens symboliques?
Vous pouvez utiliser l'utilitaire readlink
, avec l'option -f
:
-f, --canonicalize
canonicalize by following every symlink in every component of the given name recursively; all but the last component must exist
Certaines distributions, par exemple celles qui utilisent GNU coreutils et FreeBSD , sont également fournies avec un utilitaire realpath(1)
qui appelle simplement realpath(3)
et fait à peu près la même chose.
Portablement, la variable PWD
est définie par le shell à un emplacement absolu du répertoire courant. Tout composant de ce chemin peut être un lien symbolique.
case $f in
/*) absolute=$f;;
*) absolute=$PWD/$f;;
esac
Si vous souhaitez également supprimer .
Et ..
, Accédez au répertoire contenant le fichier et obtenez $PWD
À cet endroit:
if [ -d "$f" ]; then f=$f/.; fi
absolute=$(cd "$(dirname -- "$f")"; printf %s. "$PWD")
absolute=${absolute%?}
absolute=$absolute/${f##*/}
Il n'y a aucun moyen portable de suivre les liens symboliques. Si vous avez un chemin vers un répertoire, alors sur la plupart des unités, $(cd -- "$dir" && pwd -P 2>/dev/null || pwd)
fournit un chemin qui n'utilise pas de liens symboliques, car les shells qui suivent les liens symboliques ont tendance à implémenter pwd -P
("P" pour "physique").
Certains unités fournissent un utilitaire pour imprimer le chemin "physique" vers un fichier.
readlink -f
, tout comme FreeBSD ≥8.3, NetBSD ≥4.0 et OpenBSD dans le passé) comme 2.2.realpath
(il est également présent sur certains systèmes Linux et se trouve dans BusyBox).Si Perl est disponible, vous pouvez utiliser le module Cwd
.
Perl -MCwd -e 'print Cwd::realpath($ARGV[0])' path/to/file
pwd
est-il adapté à vos besoins? Il donne le chemin absolu du répertoire courant. Ou peut-être que vous voulez realpath () .
alister
et rss67
in cet article présente la manière la plus stable, compatible et la plus simple. Je n'ai jamais vu de meilleure façon que celle-ci auparavant.
RELPATH=./../
cd $RELPATH
ABSPATH=`pwd`
Si vous souhaitez revenir à l'emplacement d'origine,
ORGPATH=`pwd`
RELPATH=./../
cd $RELPATH
ABSPATH=`pwd`
cd $ORGPATH
ou
RELPATH=./../
cd $RELPATH
ABSPATH=`pwd`
cd -
Je souhaite que cela aide. C'était la meilleure solution pour moi.
En respectant la réponse de tout le monde, j'ai trouvé la fonction ci-dessous très facile et portable entre Linux/MAC OSX que d'autres que j'ai trouvées partout. Pourrait aider quelqu'un.
#!/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
Les autres réponses ici étaient correctes mais insuffisantes pour mes besoins. J'avais besoin d'une solution que je pouvais utiliser dans mes scripts sur n'importe quelle machine. Ma solution a été d'écrire un script Shell que je peux invoquer depuis les scripts où j'en ai besoin.
#!/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
Cette solution est écrite pour le Bourne Shell pour la portabilité. J'ai ceci dans un script nommé "respath.sh".
Ce script peut être utilisé comme ceci:
respath.sh '/path/to/file'
Ou comme ça
respath.sh '/relative/path/here' '/path/to/resolve/relative/to'
Le script résout le chemin dans le premier argument en utilisant le chemin du deuxième argument comme point de départ. Si seul le premier argument est fourni, le script résout le chemin relatif à votre répertoire de travail actuel.
Dans le cas, en outre, vous disposez d'un chemin prédéfini pour $1
(d'habitude ${PWD}
), les éléments suivants fonctionneraient:
CWD="${1:-${PredefinedAbsolutePath}}"
if [ "${CWD}" != "${PredefinedAbsolutePath}}" ]; then
case $1 in
/*) echo "CWD=${CWD}"; ;;
*) CWD=$(realpath $1); echo "CWD=${CWD}"; ;;
esac
fi