En Linux, la readlink
utilidad acepta una opción -f
que sigue enlaces adicionales. Esto no parece funcionar en Mac y posiblemente en sistemas basados en BSD. ¿Cuál sería el equivalente?
Aquí hay información de depuración:
$ which readlink; readlink -f
/usr/bin/readlink
readlink: illegal option -f
usage: readlink [-n] [file ...]
readlink
puede ser un comando incorporado o un comando externo.touch myfile ; ln -s myfile otherfile ; perl -MCwd=abs_path -le 'print abs_path readlink(shift);' otherfile
... en mi caso, veo: / Users / cito / myfile`. Lo agregué a mi respuesta a continuación. Salud.Respuestas:
readlink -f
hace dos cosas:Si lo desea, puede crear un script de shell que utilice el comportamiento de enlace de lectura de vainilla para lograr lo mismo. Aquí hay un ejemplo. Obviamente, podría insertar esto en su propio script donde le gustaría llamar
readlink -f
Tenga en cuenta que esto no incluye ningún manejo de errores. De particular importancia, no detecta ciclos de enlace simbólico. Una manera simple de hacer esto sería contar la cantidad de veces que da la vuelta al ciclo y falla si golpea un número improbablemente grande, como 1,000.
EDITADO para usar en
pwd -P
lugar de$PWD
.Tenga en cuenta que este script espera que se le llame como
./script_name filename
, no-f
, cambie$1
a$2
si desea poder usarlo con el-f filename
enlace de lectura GNU similar.fuente
foo -> /var/cux
, entoncesfoo/bar
no se resolverá, porquebar
no es un enlace, aunque lofoo
es.cd "$(dirname "$TARGET_FILE")"
yTARGET_FILE=$(readlink "$TARGET_FILE")
yTARGET_FILE=$(basename "$TARGET_FILE")
en los lugares apropiados en el código anterior.MacPorts y Homebrew proporcionan un paquete coreutils que contiene
greadlink
(GNU readlink). Crédito a la publicación de Michael Kallweitt en mackb.com.fuente
.bashrc
:export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH"
pwd -P
yreadlink
en OS X, sin instalar nadaPATH
. Hizo lo anterior comenzando conbrew install <package> --default-names
. Muchas veces una pregunta en este sitio se ha respondido ligeramente, o más, fuera de los requisitos técnicos del autor de la pregunta, pero dentro de una situación similar, y aún ha sido muy útil. topbug.net/blog/2013/04/14/…Te puede interesar
realpath(3)
, o Pythonos.path.realpath
. Los dos no son exactamente lo mismo; la llamada a la biblioteca C requiere que existan componentes de ruta intermedios, mientras que la versión Python no.Sé que dijiste que preferirías algo más liviano que otro lenguaje de script, pero en caso de que compilar un binario sea insufrible, puedes usar Python y ctypes (disponibles en Mac OS X 10.5) para ajustar la llamada a la biblioteca:
Irónicamente, la versión C de este script debería ser más corta. :)
fuente
realpath
hecho es lo que quiero. Pero parece bastante incómodo que tenga que compilar un binario para obtener esta función de un script de shell.readlink
, ¿verdad?)python -c "import os,sys; print(os.path.realpath(os.path.expanduser(sys.argv[1])))" "${1}"
funciona con caminos como'~/.symlink'
perl -MCwd=abs_path -le 'print abs_path readlink(shift);'
a mi respuesta :-)Odio seguir con otra implementación, pero necesitaba a) una implementación portátil y de shell puro , yb) cobertura de prueba unitaria , ya que el número de casos límite para algo como esto no es trivial .
Vea mi proyecto en Github para pruebas y código completo. Lo que sigue es una sinopsis de la implementación:
Como Keith Smith señala astutamente,
readlink -f
hace dos cosas: 1) resuelve los enlaces simbólicos de forma recursiva y 2) canoniza el resultado, por lo tanto:Primero, la implementación del solucionador de enlaces simbólicos:
Tenga en cuenta que esta es una versión ligeramente simplificada de la implementación completa . La implementación completa agrega una pequeña verificación para los ciclos de enlace simbólico , así como también masajea un poco la salida.
Finalmente, la función para canonizar una ruta:
Eso es todo, más o menos. Suficientemente simple para pegar en su script, pero lo suficientemente complicado como para que se vuelva loco al confiar en cualquier código que no tenga pruebas unitarias para sus casos de uso.
fuente
local
palabra clave que no es POSIXreadlink -f
, ni derealpath
. Asumiendo una Mac con la fórmula coreutils instalada (con lagreadlink
disponible), intente esto conln -s /tmp/linkeddir ~/Documents
;greadlink -f /tmp/linkeddir/..
imprime su directorio de inicio (resolvió el/tmp/linkeddir
enlace antes de aplicar la..
referencia de directorio principal), pero su código produce/private/tmp/
como/tmp/linkeddir/..
no es un enlace simbólico, pero-d /tmp/linkeddir/..
es verdadero y locd /tmp/linkeddir/..
lleva a/tmp
, cuya ruta canónica es/private/tmp
. Su código hace lo querealpath -L
hace, en su lugar.Un simple one-liner en perl que seguramente funcionará en casi todas partes sin ninguna dependencia externa:
Desreferenciará enlaces simbólicos.
El uso en un script podría ser así:
fuente
-l
, comoperl -MCwd -le 'print Cwd::abs_path shift' ~/non-absolute/file
greadlink es el gnu readlink que implementa -f. Puedes usar macports u otros también, prefiero homebrew.
fuente
Hice un script llamado realpath personalmente que se parece a algo así como:
fuente
sys.argv[1]
si desea que el script imprima la ruta real del primer argumento.sys.argv[0]
solo imprime la ruta real del script pyton en sí mismo, lo que no es muy útil.~/.profile
:alias realpath="python -c 'import os, sys; print os.path.realpath(sys.argv[1])'"
readlink -f
, aquí hay una versión modificada del alias de @jwhitlock para admitir una posible-f
bandera:alias realpath="python -c 'import os, sys; print os.path.realpath(sys.argv[2] if sys.argv[1] == \"-f\" else sys.argv[1])'"
¿Qué hay de esto?
fuente
../../../
->/
/usr/bin/
por ejemplo, comoalternatives
le gusta tener al sistema.Aquí hay una función de shell portátil que debería funcionar en CUALQUIERA shell comparable de Bourne. Resolverá la puntuación relativa de ruta ".. o". y desreferenciar enlaces simbólicos.
Si por alguna razón no tiene un comando realpath (1) o readlink (1), esto puede ser alias.
Disfrutar:
Además, en caso de que alguien esté interesado, aquí es cómo implementar basename y dirname en código de shell 100% puro:
Puede encontrar la versión actualizada de este código de shell en mi sitio de Google: http://sites.google.com/site/jdisnard/realpath
EDITAR: Este código tiene licencia bajo los términos de la licencia de 2 cláusulas (estilo freeBSD). Puede encontrar una copia de la licencia siguiendo el hipervínculo anterior a mi sitio.
fuente
FreeBSD y OSX tienen una versión de
stat
derivada de NetBSD.Puede ajustar la salida con modificadores de formato (consulte las páginas del manual en los enlaces anteriores).
Algunas versiones de OS X
stat
pueden carecer de la-f%R
opción de formatos. En este caso-stat -f%Y
puede ser suficiente. La-f%Y
opción mostrará el objetivo de un enlace simbólico, mientras que-f%R
muestra el nombre de ruta absoluto correspondiente al archivo.EDITAR:
Si puede usar Perl (Darwin / OS X viene instalado con versiones recientes de
perl
), entonces:trabajará.
fuente
R
opción de-f%
falta. Posiblementestat -f%Y
da la salida deseada. Ajustaré la respuesta. Tenga en cuenta que lastat
herramienta apareció en FreeBSD en la versión 4.10 y NetBSD en la versión 1.6.La forma más fácil de resolver este problema y habilitar la funcionalidad de readlink en Mac con Homebrew instalado o FreeBSD es instalar el paquete 'coreutils'. También puede ser necesario en ciertas distribuciones de Linux y otros sistemas operativos POSIX.
Por ejemplo, en FreeBSD 11, instalé invocando:
# pkg install coreutils
En MacOS con Homebrew, el comando sería:
$ brew install coreutils
No estoy seguro de por qué las otras respuestas son tan complicadas, eso es todo. Los archivos no están en un lugar diferente, simplemente no están instalados todavía.
fuente
brew install coreutils --with-default-names
para ser más especifico. O que va a terminar con "greadlink" en lugar ...pwd -P
es bastante simple pero desaparece entre muchas otras respuestas, incluidas las respuestas repetidas, de ahí el voto negativo.Comenzar actualización
Este es un problema tan frecuente que hemos creado una biblioteca Bash 4 para uso gratuito (licencia MIT) llamada realpath-lib . Está diseñado para emular readlink -f de forma predeterminada e incluye dos conjuntos de pruebas para verificar (1) que funciona para un sistema Unix determinado y (2) contra readlink -f si está instalado (pero esto no es obligatorio). Además, se puede usar para investigar, identificar y desenrollar enlaces simbólicos profundos y rotos y referencias circulares, por lo que puede ser una herramienta útil para diagnosticar problemas de directorios y archivos físicos o simbólicos profundamente anidados. Se puede encontrar en github.com o bitbucket.org .
Fin de actualización
Otra solución muy compacta y eficiente que no se basa en nada más que Bash es:
Esto también incluye una configuración de entorno
no_symlinks
que proporciona la capacidad de resolver enlaces simbólicos al sistema físico. Siempre y cuandono_symlinks
se establezca en algo, es decirno_symlinks='on'
, los enlaces simbólicos se resolverán en el sistema físico. De lo contrario, se aplicarán (la configuración predeterminada).Esto debería funcionar en cualquier sistema que proporcione Bash y devolverá un código de salida compatible con Bash para fines de prueba.
fuente
Ya hay muchas respuestas, pero ninguna funcionó para mí ... Así que esto es lo que estoy usando ahora.
fuente
$target
es una ruta, solo funciona si es un archivo.Una manera perezosa que funciona para mí
fuente
Mejor tarde que nunca, supongo. Estaba motivado para desarrollar esto específicamente porque mis scripts de Fedora no funcionaban en la Mac. El problema son las dependencias y Bash. Las Mac no las tienen, o si las tienen, a menudo están en otro lugar (otra ruta). La manipulación de la ruta de dependencia en un script Bash multiplataforma es un dolor de cabeza en el mejor de los casos y un riesgo de seguridad en el peor, por lo que es mejor evitar su uso, si es posible.
La función get_realpath () a continuación es simple, centrada en Bash y no se requieren dependencias. Solo uso el eco integrado de Bash y CD de . También es bastante seguro, ya que todo se prueba en cada etapa del camino y devuelve condiciones de error.
Si no desea seguir los enlaces simbólicos, coloque set -P en la parte delantera del script, pero de lo contrario, cd debería resolver los enlaces simbólicos por defecto. Se ha probado con argumentos de archivo que son {absolutos | pariente | enlace simbólico | local} y devuelve la ruta absoluta al archivo. Hasta ahora no hemos tenido ningún problema con eso.
Puede combinar esto con otras funciones get_dirname, get_filename, get_stemname y validate_path. Estos se pueden encontrar en nuestro repositorio de GitHub como realpath-lib (divulgación completa: este es nuestro producto, pero lo ofrecemos gratuitamente a la comunidad sin restricciones). También podría servir como herramienta de instrucción: está bien documentado.
Hemos hecho todo lo posible para aplicar las llamadas prácticas de 'Bash moderno', pero Bash es un tema importante y estoy seguro de que siempre habrá margen de mejora. Requiere Bash 4+, pero podría funcionar con versiones anteriores si todavía están disponibles.
fuente
Dado que mi trabajo es utilizado por personas con Linux no BSD y macOS, he optado por usar estos alias en nuestros scripts de compilación (
sed
incluido porque tiene problemas similares):Comprobación opcional que puede agregar para instalar automáticamente homebrew + coreutils dependencias de :
Supongo que para ser verdaderamente "global" necesita verificar a otros ... pero eso probablemente se acerca a la marca 80/20.
fuente
Explicación
coreutils es un
brew
paquete que instala las utilidades principales de GNU / Linux que corresponden a la implementación de Mac OSX de ellas para que pueda usarlasPuede encontrar programas o utilidades en su sistema mac osx que parecen similares a los coreutils de Linux ("Core Utilities") pero difieren en algunos aspectos (como tener diferentes indicadores).
Esto se debe a que la implementación de Mac OSX de estas herramientas es diferente. Para obtener el comportamiento original de GNU / Linux, puede instalar el
coreutils
paquete a través delbrew
sistema de administración de paquetes.Esto instalará las utilidades principales correspondientes, precedidas por
g
. Por ejemploreadlink
, encontrará ungreadlink
programa correspondiente .Para que
readlink
funcione como la implementación GNUreadlink
(greadlink
), puede crear un alias simple después de instalar coreutils.Implementación
Siga las instrucciones en https://brew.sh/
brew install coreutils
Puede colocar su alias en ~ / .bashrc, ~ / .bash_profile, o donde esté acostumbrado a mantener sus alias bash. Yo personalmente mantengo el mío en ~ / .bashrc
alias readlink=greadlink
Puede crear alias similares para otros coreutils como gmv, gdu, gdf, etc. Pero tenga en cuenta que el comportamiento de GNU en una máquina Mac puede ser confuso para otros acostumbrados a trabajar con coreutils nativos, o puede comportarse de manera inesperada en su sistema Mac.
fuente
Escribí una utilidad realpath para OS X que puede proporcionar los mismos resultados que
readlink -f
.Aquí hay un ejemplo:
Si está usando MacPorts, puede instalarlo con el siguiente comando:
sudo port selfupdate && sudo port install realpath
.fuente
Verdaderamente independiente de la plataforma también sería este R-onliner
Para imitar realmente
readlink -f <path>
, sería necesario usar $ 2 en lugar de $ 1.fuente
readlink -f
Implementación compatible con POSIX para scripts de shell POSIXhttps://github.com/ko1nksm/readlinkf
Esto es compatible con POSIX (sin bashism). No usa ni
readlink
nirealpath
. He verificado que es exactamente lo mismo comparándolo con GNUreadlink -f
(ver resultados de la prueba ). Tiene manejo de errores y buen rendimiento. Puede reemplazar con seguridad desdereadlink -f
. La licencia es CC0, por lo que puede usarla para cualquier proyecto.Por favor, consulte el último código. Puede algunos arreglado.
fuente
Perl tiene una función de enlace de lectura (por ejemplo, ¿cómo copio enlaces simbólicos en Perl? ). Esto funciona en la mayoría de las plataformas, incluido OS X:
Por ejemplo:
fuente
readlink
sin la-f
opción (sin recursión, sin ruta absoluta), por lo que también podría usarloreadlink
directamente.La respuesta de @Keith Smith da un bucle infinito.
Aquí está mi respuesta, que solo uso en SunOS (SunOS pierde muchos comandos POSIX y GNU).
Es un archivo de script que debe colocar en uno de sus directorios $ PATH:
fuente
Esto es lo que uso:
stat -f %N $your_path
fuente
Las rutas a readlink son diferentes entre mi sistema y el tuyo. Intente especificar la ruta completa:
fuente
readlink
que es compatible con GNU. Es bueno saberlo, pero no resuelve mi problema, ya que necesito que mi script se ejecute en la máquina de otras personas, y no puedo requerir que instalen fink para eso.