452 votes

Comment puis-je obtenir le comportement de readlink -f de GNU sur un Mac?

Sous Linux, l'utilitaire readlink accepte une option -f qui suit les liens supplémentaires. Cela ne semble pas fonctionner sur les systèmes basés sur Mac et éventuellement BSD. Quel serait l'équivalent?

Voici quelques informations de débogage:

 $ which readlink; readlink -f
/usr/bin/readlink
readlink: illegal option -f
usage: readlink [-n] [file ...]
 

487voto

tomyjwu Points 847

macports et homebrew fournissent un paquet coreutils contenant greadlink (readlink GNU). crédit à Michael Kallweitt dans mackb.com

207voto

Keith Smith Points 1724

"readlink -f" ne signifie deux choses:

  1. Il parcourt le long d'une séquence de liens symboliques jusqu'à ce qu'il trouve un fichier réel.
  2. Il retourne que le fichier d' standardisée nom de l'---c'est à dire, son chemin absolu.

Si vous le souhaitez, vous pouvez créer un script shell qui utilise de la vanille readlink comportement afin de réaliser la même chose. Voici un exemple. Évidemment, vous pouvez insérer dans votre propre script où vous voulez l'appeler "readlink -f":

#!/bin/sh

TARGET_FILE=$1

cd `dirname $TARGET_FILE`
TARGET_FILE=`basename $TARGET_FILE`

# Iterate down a (possible) chain of symlinks
while [ -L "$TARGET_FILE" ]
do
    TARGET_FILE=`readlink $TARGET_FILE`
    cd `dirname $TARGET_FILE`
    TARGET_FILE=`basename $TARGET_FILE`
done

# Compute the canonicalized name by finding the physical path 
# for the directory we're in and appending the target file.
PHYS_DIR=`pwd -P`
RESULT=$PHYS_DIR/$TARGET_FILE
echo $RESULT

Notez que ce n'est pas inclure toute erreur de manipulation. D'une importance particulière, il ne détecte pas de lien symbolique cycles. Une façon simple de le faire est de compter le nombre de fois que vous aller autour de la boucle et échouer si vous frappez un incroyablement grand nombre, comme de 1 000.

ÉDITÉ à l'usage "pwd -P" à la place de $PWD.

48voto

Miles Points 12977

Vous pouvez être intéressé par realpath(3), ou Python os.path.realpath. Les deux ne sont pas exactement les mêmes; la bibliothèque C d'appel exige l'intermédiaire de chemin de composants existent, tandis que la version de Python ne le fait pas.

$ pwd
/tmp/foo
$ ls -l
total 16
-rw-r--r--  1 miles    wheel  0 Jul 11 21:08 a
lrwxr-xr-x  1 miles    wheel  1 Jul 11 20:49 b -> a
lrwxr-xr-x  1 miles    wheel  1 Jul 11 20:49 c -> b
$ python -c 'import os,sys;print os.path.realpath(sys.argv[1])' c
/private/tmp/foo/a

Je sais que vous l'avez dit vous préférez quelque chose de plus léger qu'un autre langage de script, mais seulement dans le cas de la compilation d'un fichier binaire est insupportable, vous pouvez utiliser Python et ctypes (disponible sur Mac OS X 10.5) pour encapsuler l'appel de la bibliothèque:

#!/usr/bin/python

import ctypes, sys

libc = ctypes.CDLL('libc.dylib')
libc.realpath.restype = ctypes.c_char_p
libc.__error.restype = ctypes.POINTER(ctypes.c_int)
libc.strerror.restype = ctypes.c_char_p

def realpath(path):
    buffer = ctypes.create_string_buffer(1024) # PATH_MAX
    if libc.realpath(path, buffer):
        return buffer.value
    else:
        errno = libc.__error().contents.value
        raise OSError(errno, "%s: %s" % (libc.strerror(errno), buffer.value))

if __name__ == '__main__':
    print realpath(sys.argv[1])

Ironiquement, la version C de ce script devrait être plus courte. :)

27voto

user15569 Points 141
  1. Installer homebrew
  2. Exécuter "infuser installer coreutils"
  3. Exécutez "greadlink -f path"

greadlink est le readlink gnu qui implémente -f. Vous pouvez utiliser macports ou d'autres, je préfère homebrew.

21voto

James Points 196

J'ai fait un script appelé realpath personnellement qui ressemble un peu à quelque chose comme:

 #!/usr/bin/env python
import os,sys
print os.path.realpath(sys.argv[1])
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X