Pregunta: ¿hay un comando simple sh / bash / zsh / fish / ... para imprimir la ruta absoluta de cualquier archivo que lo alimente?
Caso de uso: Estoy en el directorio /a/b
y me gustaría para imprimir la ruta completa al archivo c
en la línea de comandos para que pueda pegar fácilmente en otro programa: /a/b/c
. Simple, pero un pequeño programa para hacer esto probablemente podría ahorrarme aproximadamente 5 segundos cuando se trata de manejar caminos largos, lo que al final se suma. Entonces me sorprende que no puedo encontrar una utilidad estándar para hacer esto, ¿realmente no hay ninguna?
Aquí hay una implementación de muestra, abspath.py:
#!/usr/bin/python
# Author: Diggory Hardy <[email protected]>
# Licence: public domain
# Purpose: print the absolute path of all input paths
import sys
import os.path
if len(sys.argv)>1:
for i in range(1,len(sys.argv)):
print os.path.abspath( sys.argv[i] )
sys.exit(0)
else:
print >> sys.stderr, "Usage: ",sys.argv[0]," PATH."
sys.exit(1)
Respuestas:
Tratar
realpath
.fuente
realpath
consta de: github.com/westonruter/misc-cli-tools/blob/master/realpathPruebe
readlink
cuál resolverá los enlaces simbólicos:fuente
-m
es la mejor opción para usar./usr/bin/readlink
en Mavericks. ¿O quiso decir que esas opciones no se encuentran en OS X? Parece ser una versión BSD atrofiada ...: preadlink
manual de BSD :only the target of the symbolic link is printed. If the given argument is not a symbolic link, readlink will print nothing and exit with an error
por lo tanto, readlink no funcionará para este propósito en OSXfuente
a b
(dos espacios entre a y b, SO se come uno de ellos).function realpath { echo $(cd $(dirname $1); pwd)/$(basename $1); }
hacerme unrealpath
comando (respuesta actualmente aceptada) en OS X. ¡Gracias!LOG=$(echo $(cd $(dirname $0); pwd)/$(basename $0 .sh).log)
Olvídate
readlink
yrealpath
qué puede o no estar instalado en tu sistema.Ampliando la respuesta anterior de dogbane aquí se expresa como una función:
entonces puedes usarlo así:
¿Cómo y por qué funciona?
La solución explota el hecho de que el
pwd
comando incorporado Bash imprimirá la ruta absoluta del directorio actual cuando se invoque sin argumentos.¿Por qué me gusta esta solución?
Es portátil y no requiere ninguno
readlink
orealpath
que a menudo no existe en una instalación predeterminada de una distribución de Linux / Unix dada.¿Qué pasa si el directorio no existe?
Como se indicó anteriormente, la función fallará e imprimirá en stderr si la ruta de directorio dada no existe. Esto puede no ser lo que quieres. Puede expandir la función para manejar esa situación:
Ahora devolverá una cadena vacía si uno de los directorios principales no existe.
¿Cómo manejas el final '..' o '.' en entrada?
Bueno, da un camino absoluto en ese caso, pero no uno mínimo. Se verá así:
Si desea resolver el '...', deberá crear el script como:
fuente
realpath
proviene del paquete coreutils, que también contiene herramientas comowho
,touch
ocat
. Es un conjunto bastante estándar de herramientas GNU, por lo que puede estar seguro de que está instalado en casi cualquier máquina basada en Linux. Dicho esto, tiene razón: hay 2 problemas con él: i) probablemente lo perderá en la instalación predeterminada en sistemas unix que no son GNU (como OpenBSD) ii) esta herramienta se introdujo en la versión 8.15 (por lo que es bastante nueva, desde 2012), por lo que la echará de menos en sistemas estables a largo plazo (como RHEL 6).Esto es mejor que
readlink -e FILE
orealpath
, porque funciona incluso si el archivo no existe.fuente
-m
opción no está disponible en Mavericks.Esta ruta relativa a la función de shell del convertidor de ruta absoluta
cd
ypwd
)..
y.
Código:
Muestra:
Nota: Esto se basa en las respuestas de nolan6000 y bsingh , pero corrige el caso del archivo.
También entiendo que la pregunta original era sobre una utilidad de línea de comando existente. Pero dado que esta parece ser LA pregunta sobre stackoverflow para eso, incluidos los scripts de shell que desean tener dependencias mínimas, puse esta solución de script aquí, para que pueda encontrarla más tarde :)
fuente
$ abspath 'a b c/file.txt'
Eso se debe a que el argumentocd
no se cita. Para superar esto, en lugar de citar todo el argumento paraecho
(¿hay alguna razón para estas citas?), Cite solo los argumentos de ruta. Es decir, reemplazarecho "$(cd ${1%/*}; pwd)/${1##*/}"
conecho $(cd "${1%/*}"; pwd)/${1##*/}
.echo "$(cd "$1"; pwd)"
con(cd "$1"; pwd)
. No hay necesidad de eco aquí.( ... )
todavía son necesarias, por lo quecd
sucede en una subshell, ya que no queremos cambiar el directorio de trabajo para ninguna persona que llameabspath
.El
find
comando puede ayudarEnumera todos los archivos en o debajo del directorio actual con nombres que coinciden con el patrón. Puede simplificarlo si solo obtiene unos pocos resultados (por ejemplo, un directorio cerca de la parte inferior del árbol que contiene algunos archivos), solo
Lo uso en Solaris 10, que no tiene las otras utilidades mencionadas.
fuente
PWD
, simplemente podría usar$PWD/$filename
.Si no tiene las utilidades readlink o realpath, puede usar la siguiente función que funciona en bash y zsh (no estoy seguro del resto).
Esto también funciona para archivos inexistentes (al igual que la función python
os.path.abspath
).Lamentablemente
abspath ./../somefile
no se deshace de los puntos.fuente
echo "$1"
conprintf "%s\n" "$1"
(lo mismo con el segundo eco).echo
puede interpretar barras invertidas dentro de sus argumentos.Aquí hay una función de solo zsh que me gusta por su compacidad. Utiliza el modificador de expansión 'A'; consulte zshexpn (1).
fuente
Generalmente, no hay tal cosa como la
absolute path
de un archivo (este medio declaración de que no puede haber más de uno, en general, de ahí el uso del artículo definido el no es el caso). Unaabsolute path
es cualquier ruta que comienza desde la raíz "/" y designa un archivo sin ambigüedad independientemente del directorio de trabajo (ver, por ejemplo, wikipedia ).A
relative path
es una ruta que se debe interpretar a partir de otro directorio. Puede ser el directorio de trabajo si estárelative path
siendo manipulado por una aplicación (aunque no necesariamente). Cuando está en un enlace simbólico en un directorio, generalmente está destinado a ser relativo a ese directorio (aunque el usuario puede tener otros usos en mente).Por lo tanto, una ruta absoluta es solo una ruta relativa al directorio raíz.
Una ruta (absoluta o relativa) puede o no contener enlaces simbólicos. Si no lo hace, también es algo impermeable a los cambios en la estructura de enlace, pero esto no es necesariamente necesario ni deseable. Algunas personas llaman
canonical path
(ocanonical file name
oresolved path
) unaabsolute path
en la que se han resuelto todos los enlaces simbólicos, es decir, han sido sustituidos por un camino a la Whetever que enlazan a. Los comandosrealpath
yreadlink
ambos buscan una ruta canónica, pero solorealpath
tiene una opción para obtener una ruta absoluta sin molestarse en resolver enlaces simbólicos (junto con varias otras opciones para obtener varios tipos de rutas, absolutas o relativas a algún directorio).Esto requiere varios comentarios:
realpath
yreadlink
tienen opciones para dar cuenta de eso.canonical
. Por lo tanto, el concepto depende del tiempo (o del entorno).canonical path
en un archivo, por dos razones:ro
) en varios puntos de montaje.Por lo tanto, incluso con la definición mucho más restrictiva de
canonical path
, puede haber varias rutas canónicas a un archivo. Esto también significa que el calificadorcanonical
es algo inadecuado, ya que generalmente implica una noción de unicidad.Esto amplía una breve discusión del tema en una respuesta a otra pregunta similar en Bash: recuperar la ruta absoluta dada relativa
Mi conclusión es que
realpath
está mejor diseñado y es mucho más flexible quereadlink
. El único usoreadlink
que no está cubiertorealpath
es la llamada sin opción que devuelve el valor de un enlace simbólico.fuente
realpath
vsreadlink
o incluso sobre enlaces simbólicos excede lo que pregunté.canonical
refiere precisamente a esta singularidad en relación con un conjunto de transformaciones. Pero, por ejemplo, / dev / cdrom es una ruta absoluta perfectamente buena, aunque en realidad es un enlace a / dev / sr0. Ambos apuntan al mismo dispositivo. Mi respuesta original apuntaba a un artículo web relevante.La
dogbane
respuesta con la descripción de lo que viene:Explicación:
"$1"
dirname "$1"
cd "$(dirname "$1")
en este directorio relativo y obtenemos una ruta absoluta para él ejecutando elpwd
comando de shell$(basename "$1")
echo
sefuente
Para los directorios
dirname
se dispara../
y regresa./
.La función de nolan6000 se puede modificar para arreglar eso:
fuente
.profile
y, por lo tanto, está disponible para uso interactivo.$1
es un nombre de archivo simple:get_abs_filename foo
-> nada (o<current_dir>/foo/foo
sifoo
es un directorio).Esta no es una respuesta a la pregunta, sino para aquellos que hacen scripts:
maneja / .. ./ etc correctamente. También parece que trabajo en OSX
fuente
He colocado el siguiente script en mi sistema y lo llamo como un alias bash para cuando quiero tomar rápidamente la ruta completa a un archivo en el directorio actual:
No estoy seguro de por qué, pero en OS X cuando se llama por un script "$ PWD" se expande a la ruta absoluta. Cuando se llama al comando find en la línea de comando, no lo hace. Pero hace lo que quiero ... disfrutar.
fuente
$PWD
siempre tiene la ruta absoluta del directorio de trabajo. Además,find
no tolerará cortes, por lo que no responderá la pregunta como se le preguntó. Una forma más rápida de hacer lo que estás buscando hacer sería simplementeecho "$PWD/$1"
Probablemente, la más simple si desea utilizar solo builtins es:
Solo dos palabras adicionales para escribir, y esto funcionará en todos los sistemas Unix, así como en OSX.
fuente
-maxdepth 1
antes-name
(suponiendo que el archivo esté en el directorio actual). Sin eso, funcionará con archivos en cualquier subdirectorio de pwd, pero no con otros.find
que no encontrarás un archivo fuera del árbol de directorios debajopwd
. Por ejemplo, si lo intentasfind . -name ../existingFile
, falla.Esto compensa las deficiencias de
realpath
almacenarlo en un script de shellfullpath
. Ahora puedes llamar:fuente
realpath "foo bar"
->/home/myname/foo bar
. Si no puede molestarse en citar argumentos de la línea de comandos, norealpath
es culpa suya.Una alternativa para obtener el camino absoluto en Ruby :
realpath() {ruby -e "require 'Pathname'; puts Pathname.new('$1').realpath.to_s";}
Funciona sin argumentos (carpeta actual) y el archivo relativo y absoluto o la ruta de la carpeta como elemento.
fuente
Responde con Homebrew
realpath
es la mejor respuesta, pero si no lo tiene instalado, primero debe ejecutarbrew install coreutils
lo que instalará coreutils con muchas funciones increíbles. Escribir una función personalizada y exportarla es demasiado trabajo y riesgo de error para algo como esto, aquí hay dos líneas:fuente
Hola chicos, sé que es un hilo viejo, pero solo estoy publicando esto para referencia a cualquier otra persona que haya visitado esto como yo. Si entendí la pregunta correctamente, creo que el
locate $filename
comando. Muestra la ruta absoluta del archivo suministrado, pero solo si existe.fuente
locate
es una utilidad para buscar archivos / rutas por nombre. Puede hacer el trabajo pero también puede encontrar otras coincidencias y puede que no encuentre un archivo existente sin llamarupdatedb
primero como root.