Réponses:
Vous pouvez utiliser l' readlink
utilitaire, avec l' -f
option:
-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 realpath(1)
utilitaire qui appelle realpath(3)
et fait à peu près la même chose.
readlink
ni realpath
- Solaris et HP-UX, en particulier.
brew install coreutils
apple.stackexchange.com/a/69332/23040 , et si vous ne souhaitez pas effectuer l'étape qui redirige tous les outils CLI du Mac standard vers les équivalents GNU nouvellement installés, appelez simplement greadlink
.
De manière portable, la PWD
variable est définie par le shell sur un emplacement absolu du répertoire actuel. Tout composant de ce chemin peut être un lien symbolique.
case $f in
/*) absolute=$f;;
*) absolute=$PWD/$f;;
esac
Si vous voulez éliminer .
et ..
aussi bien, allez dans le répertoire contenant le fichier et obtenez- $PWD
y:
if [ -d "$f" ]; then f=$f/.; fi
absolute=$(cd "$(dirname -- "$f")"; printf %s. "$PWD")
absolute=${absolute%?}
absolute=$absolute/${f##*/}
Il n'y a pas de moyen portable de suivre des liens symboliques. Si vous avez un chemin d'accès à un répertoire, alors sur la plupart des ordinateurs, $(cd -- "$dir" && pwd -P 2>/dev/null || pwd)
un chemin n'utilisant pas de liens symboliques, car les shells qui suivent les liens symboliques ont tendance à être implémentés pwd -P
(«P» pour «physique»).
Certains ordinateurs fournissent un utilitaire pour imprimer le chemin «physique» vers un fichier.
readlink -f
, tout comme FreeBSD ≥8.3, NetBSD ≥4,0 et OpenBSD dès la version 2.2.realpath
(il est également présent sur certains systèmes Linux, et il est dans BusyBox).Si Perl est disponible, vous pouvez utiliser le Cwd
module .
perl -MCwd -e 'print Cwd::realpath($ARGV[0])' path/to/file
pwd
( $(cd -- "$dir" && pwd -P 2>/dev/null | pwd)
)? Il ne semble pas se soucier de stdin.
||
Est pwd
adapté à vos besoins? Il donne le chemin absolu du répertoire courant. Ou peut-être que ce que vous voulez, c'est realpath () .
alister
et rss67
dans cet article, introduisez le moyen le plus stable, compatible et le plus simple. Je n'ai jamais vu de meilleure façon que cela avant.
RELPATH=./../
cd $RELPATH
ABSPATH=`pwd`
Si vous voulez 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.
ABSPATH=$(cd -- "$RELPATH" && pwd)
. Notez les guillemets autour de la substitution (afin de ne pas rompre si le chemin contient des espaces et des caractères globulants) et le --
(dans le cas où le chemin commence par -
). De plus, cela ne fonctionne que pour les répertoires et ne canonise pas les liens symboliques comme demandé. Voir ma réponse pour plus de détails.
Les autres réponses ici étaient bien mais étaient insuffisantes pour mes besoins. J'avais besoin d'une solution que je pourrais utiliser dans mes scripts sur n'importe quelle machine. Ma solution a été d'écrire un script shell que je peux invoquer à partir des 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 shell Bourne 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.
pwd
intégré et ne prend pas en charge -P
(le shell Bourne n’a pas implémenté cette gestion logique $ PWD comme le font les shell POSIX).
cd -P --
aussi au cas où le premier argument en contiendrait ..
case
chèque devrait être à la ..|../*)
place de ..*
.
dirname $cwd
En respectant les réponses de tous les autres, j’ai trouvé la fonction ci-dessous très facile et portable entre Linux / MAC OSX et d’autres que j’ai trouvée partout. Peut 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
Supposons que la variable a stocke un nom de chemin (a = "quel que soit")
1. Pour un chemin potentiel contenant de l’espace:
c=$(grep -o " " <<< $a | wc -l); if (( $c > "0" )); then a=$(sed 's/ /\\ /g' <<< $a); fi
2. Pour la question réelle, c'est-à-dire la conversion du chemin en absolu: readlink peut extraire le contenu d'un lien symbolique, ce qui peut être utilisé comme suit. (la note readlink -f
aurait été parfaite mais n’est pas disponible dans au moins Mac OS X bash, où -f signifie FORMATS .)
if [[ $(readlink $a) == "" ]]; then a=$(cd $a; pwd); else a=$(cd $(readlink $a); pwd); fi
3. Vient d’apprendre pwd -P
dans man pwd
: -P consiste à " Afficher le répertoire de travail physique actuel (tous les liens symboliques résolus) " "et donc
if (( $(grep -o " " <<< $a | wc -l) > "0" )); then a=$(sed 's/ /\\ /g' <<< $a); fi; a=$(cd $a; pwd -P)
doit travailler aussi.
Conclusion: combinez 1 et 2 pour satisfaire vos exigences, tandis que les noms de chemins contenant des espaces sont déjà pris en charge dans le 3, plus concis .
-f
commutateur n'existe pas sur Mac OS X (au moins à partir de 10.8.5). Sans le-f
commutateur, il ne fait que renvoyer un code d'erreur.