ver script saber ruta programacion para entorno ejemplos comando archivo bash shell path

script - variables en bash



Comando bash/fish para imprimir la ruta absoluta a un archivo (17)

Pregunta: ¿hay un simple comando 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 imprimir la ruta completa al archivo c en la línea de comandos para poder pegarlo fácilmente en otro programa: /a/b/c . Simple, pero un pequeño programa para hacer esto probablemente me ahorrará unos 5 segundos cuando se trata de manejar caminos largos, lo que al final se suma. Entonces, me sorprende que no pueda encontrar una utilidad estándar para hacer esto. ¿Realmente no hay ninguna?

Aquí hay una implementación de ejemplo, 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)


Aquí hay una función solo zsh que me gusta por su compacidad. Utiliza el modificador de expansión ''A'' - vea zshexpn (1).

realpath() { for f in "$@"; do echo ${f}(:A); done }


El comando find puede ayudar

find $PWD -name ex* find $PWD -name example.log

Enumera 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, el directorio cerca de la parte inferior del árbol que contiene pocos archivos), solo

find $PWD

Lo uso en Solaris 10, que no tiene las otras utilidades mencionadas.


Esta no es una respuesta a la pregunta, pero para aquellos que hacen scripts:

echo `cd "$1" 2>/dev/null&&pwd||(cd "$(dirname "$1")";pwd|sed "s|/*/$|/${1##*/}|")`

maneja / ... ./ etc correctamente. También parece que funciona en OSX.


Esta ruta relativa a la función de shell convertidor de ruta absoluta

  • no requiere utilidades (solo cd y pwd )
  • Trabajos para directorios y archivos.
  • manijas .. y .
  • Maneja espacios en dir o nombres de archivos
  • requiere que el archivo o directorio exista
  • no devuelve nada si no existe nada en el camino dado
  • maneja rutas absolutas como entrada (las pasa esencialmente)

Código:

function abspath() { # generate absolute path from relative path # $1 : relative filename # return : absolute path if [ -d "$1" ]; then # dir (cd "$1"; pwd) elif [ -f "$1" ]; then # file if [[ $1 = /* ]]; then echo "$1" elif [[ $1 == */* ]]; then echo "$(cd "${1%/*}"; pwd)/${1##*/}" else echo "$(pwd)/$1" fi fi }

Muestra:

# assume inside /parent/cur abspath file.txt => /parent/cur/file.txt abspath . => /parent/cur abspath .. => /parent abspath ../dir/file.txt => /parent/dir/file.txt abspath ../dir/../dir => /parent/dir # anything cd can handle abspath doesnotexist => # empty result if file/dir does not exist abspath /file.txt => /file.txt # handle absolute path input

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 comandos existente. Pero ya que esta parece ser LA pregunta en para eso, incluidos los scripts de shell que desean tener dependencias mínimas, pongo esta solución de script aquí, para poder encontrarla más adelante :)


Generalmente no existe tal cosa como la absolute path de absolute path a un archivo (esta declaración significa que puede haber más de uno en general, por lo tanto, el uso del artículo definido no es apropiado). Una absolute path es cualquier ruta que se inicie desde la raíz "/" y designe un archivo sin ambigüedad independientemente del directorio de trabajo (vea por ejemplo wikipedia ).

Una relative path es una ruta que debe interpretarse comenzando desde otro directorio. Puede ser el directorio de trabajo si es una relative path que está siendo manipulada 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 o incluso deseable. Algunas personas llaman a la canonical path (o al canonical file name o la resolved path ) una absolute path en la que se han resuelto todos los enlaces simbólicos, es decir, han sido reemplazados por una ruta a la que están vinculados. Los comandos realpath y readlink buscan una ruta canónica, pero solo realpath 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:

  1. los enlaces simbólicos solo se pueden resolver si lo que se supone que están vinculados ya está creado, lo que obviamente no siempre es así. Los comandos realpath y readlink tienen opciones para dar cuenta de eso.
  2. un directorio en una ruta puede convertirse más tarde en un enlace simbólico, lo que significa que la ruta ya no es canonical . Por lo tanto, el concepto depende del tiempo (o del entorno).
  3. incluso en el caso ideal, cuando todos los enlaces simbólicos pueden resolverse, todavía puede haber más de una canonical path a un archivo, por dos razones:
    • la partición que contiene el archivo puede haberse montado simultáneamente ( ro ) en varios puntos de montaje.
    • puede haber enlaces duros al archivo, lo que significa que esencialmente el archivo existe en varios directorios diferentes.

Por lo tanto, incluso con la definición mucho más restrictiva de la canonical path , puede haber varias rutas canónicas a un archivo. Esto también significa que el calificador canonical es algo inadecuado, ya que generalmente implica una noción de singularidad.

Esto expande 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 que readlink . El único uso de readlink que no está cubierto por realpath es la llamada sin opción que devuelve el valor de un enlace simbólico.


He colocado la siguiente secuencia de comandos en mi sistema y la llamo como un alias de bash para cuando quiera capturar rápidamente la ruta completa a un archivo en el directorio actual:

#!/bin/bash /usr/bin/find "$PWD" -maxdepth 1 -mindepth 1 -name "$1"

No estoy seguro de por qué, pero, en OS X cuando se llama mediante una secuencia de comandos "$ PWD" se expande a la ruta absoluta. Cuando el comando de búsqueda se llama en la línea de comandos, no lo hace. Pero hace lo que quiero ... disfrutar.


Hola chicos, se que es un tema antiguo, pero estoy publicando esto como referencia a cualquier otra persona que haya visitado esto como yo. Si entendí la pregunta correctamente, creo que el comando locate $filename . Muestra la ruta absoluta del archivo suministrado, pero solo si existe.


Intente readlink el enlace que resolverá los enlaces simbólicos:

readlink -e /foo/bar/baz


Olvídese de readlink y realpath que pueden o no estar instalados en su sistema.

Ampliando la respuesta de dogbane aquí arriba, se expresa como una función:

#!/bin/bash get_abs_filename() { # $1 : relative filename echo "$(cd "$(dirname "$1")" && pwd)/$(basename "$1")" }

entonces puedes usarlo así:

myabsfile=$(get_abs_filename "../../foo/bar/file.txt")

¿Cómo y por qué funciona?

La solución explota el hecho de que el comando pwd incorporado de 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 ni readlink ni realpath que a menudo no existe en una instalación predeterminada de una distro Linux / Unix determinada.

¿Qué pasa si dir no existe?

Como se indicó anteriormente, la función fallará e imprimirá en stderr si la ruta del directorio dada no existe. Esto puede no ser lo que quieres. Puedes expandir la función para manejar esa situación:

#!/bin/bash get_abs_filename() { # $1 : relative filename if [ -d "$(dirname "$1")" ]; then echo "$(cd "$(dirname "$1")" && pwd)/$(basename "$1")" fi }

Ahora devolverá una cadena vacía si no existe uno de los directorios principales.

¿Cómo manejas el ''...'' o ''.'' en la entrada?

Bueno, da un camino absoluto en ese caso, pero no mínimo. Se verá como

/Users/bob/Documents/..

Si desea resolver el ''...'' necesitará hacer el script como:

get_abs_filename() { # $1 : relative filename filename=$1 parentdir=$(dirname "${filename}") if [ -d "${filename}" ]; then echo "$(cd "${filename}" && pwd)" elif [ -d "${parentdir}" ]; then echo "$(cd "${parentdir}" && pwd)/$(basename "${filename}")" fi }


Para directorios dirname se dispara para ../ y devuelve ./ .

La función de nolan6000 se puede modificar para corregir eso:

get_abs_filename() { # $1 : relative filename if [ -d "${1%/*}" ]; then echo "$(cd ${1%/*}; pwd)/${1##*/}" fi }


Prueba realpath .

$ realpath example.txt /home/username/example.txt


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).

abspath () { case "$1" in /*)printf "%s/n" "$1";; *)printf "%s/n" "$PWD/$1";; esac; }

Esto también funciona para archivos inexistentes (al igual que la función python os.path.abspath ).

Desafortunadamente, abspath ./../somefile no elimina los puntos.


The dogbane answer con la descripción de lo que viene:

#! /bin/sh echo "$(cd "$(dirname "$1")"; pwd)/$(basename "$1")"

Explicación:

  1. Este script obtiene la ruta relativa como argumento "$1"
  2. Luego obtenemos la parte dirname de esa ruta (puede pasar dir o file a este script): dirname "$1"
  3. Luego, cd "$(dirname "$1") en este directorio relativo y obtenemos una ruta de acceso absoluta ejecutando el comando pwd shell
  4. Después de eso, agregamos el nombre base a la ruta absoluta: $(basename "$1")
  5. Como paso final lo hacemos echo .

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 una ruta de archivo o carpeta relativa y absoluta como un documento.


#! /bin/bash file="$@" realpath "$file" 2>/dev/null || eval realpath $(echo $file | sed ''s/ /// /g'')

Esto compensa las deficiencias de realpath , guárdelo en una fullpath shell fullpath . Ahora puedes llamar:

$ cd && touch a/ a && rm A 2>/dev/null $ fullpath "a a" /home/user/a a $ fullpath ~/a/ a /home/user/a a $ fullpath A A: No such file or directory.


#! /bin/sh echo "$(cd "$(dirname "$1")"; pwd -P)/$(basename "$1")"


$ readlink -m FILE /path/to/FILE

Esto es mejor que readlink -e FILE o realpath , porque funciona incluso si el archivo no existe.