Estoy escribiendo un guión para establecer variables de entorno en linux 2.6 usando bash.
Así que la secuencia de comandos contiene comandos como:

export SRC_DIR=..
export LIBPATH=${SRC_DIR}/lib

el problema es que cuando trato de hacer echo $LIBPATH, se muestra «../lib» en oposición a la expansión de la SRC_DIR a la ruta de acceso completa. Me gustaría que la secuencia de comandos para imprimir algo como /home/x/lib como contraposición a ../lib.

ACTUALIZACIÓN
La secuencia de comandos debe evaluar SRC_DIR a ser un directorio a partir de la secuencia de comandos de ubicación y no en el directorio actual desde donde la secuencia de comandos se invoca

  • la búsqueda de [bash] relative path muestra 2479 respuestas. Buena suerte a todos.
InformationsquelleAutor Jimm | 2012-07-23

7 Comentarios

  1. 58

    De cambio de Directorio en Subshell

    Hay un pequeño truco que puede utilizar para obtener la ruta absoluta de una ruta de acceso relativa sin cambiar el directorio actual de trabajo. El truco es mover a la ruta de acceso relativa en un subshell, y, a continuación, expanda el directorio de trabajo. Por ejemplo:

    export SRC_DIR=$(cd ..; pwd)

    Rutas relativas de secuencia de Comandos en Lugar de la Invocación, el Directorio

    Para cambiar a una ruta de acceso relativa de una secuencia de comandos de ubicación, en lugar de en el directorio de trabajo actual, puede utilizar una parámetro de expansión o la dirname utilidad. Yo prefiero dirname, ya que es un poco más explícito. Aquí están dos ejemplos.

    # Using /usr/bin/dirname.
    export SRC_DIR=$(cd "$(dirname "$0")/.."; pwd)
    
    # Using the "remove matching suffix pattern" parameter expansion.
    export SRC_DIR=$(cd "${0%/*}/.."; pwd)
    • Lo siento, habló temprano. Este tiene el mismo problema que el script debe ser ejecutado desde la carpeta donde se encuentra. Pero si ejecuto el script de arriba de /tmp, el SRC_DIR evaluar a la carpeta raíz como /
    • PEBKAC. Si colocas el script en /tmp y, a continuación, proporcionar una ruta de acceso relativa de «..» de la escritura, dirname, entonces, por supuesto, obtener /. Usted probablemente querrá «../src» o algún otro similar de la construcción.
  2. 14

    La readlink comando es capaz no sólo de la resolución de enlaces simbólicos, pero también canonicalizing rutas de acceso relativas. Tenga cuidado, ya que puede que no desee que el comportamiento de resolución de enlaces simbólicos en todas las secuencias de comandos. Si usted no desea resolver enlaces simbólicos, pwd sería la mejor; nota el uso de un subshell, por lo que el comando cd no afecta el directorio de trabajo en la cáscara principal.

    # The path you want to get information on... (for readability)
    your_path=..
    
    # Using /bin/readlink (resolves symlinks)
    export SRC_DIR=$(readlink --canonicalize $your_path)
    
    # Using /usr/bin/dirname (keeps symlinks)
    export SRC_DIR=$(cd $your_path ; pwd)
  3. 8

    Yo normalmente uso

    SCRIPT_DIR=$(readlink -f ${0%/*})

    Debe devolver la ruta de acceso completa a la secuencia de comandos, e incluso resuelve todos los enlaces a lo largo del camino.

    • Este tiene el mismo problema que $0 se evalúa a la palabra de bash. Mi primera línea en el script #!/usr/bin/env bash. Cuando me echo $SCRIPT_DIR, que hace la ruta de la expansión, sino que también añade la palabra de bash. Estoy ejecutando el archivo directamente ./env.sh
  4. 0

    Hacer esto en su lugar:

    export SRC_DIR=`pwd`;

    Actualización:

    Porque usted desea que la ruta de acceso relativa a la secuencia de comandos de ubicación en el sistema de archivos, el uso de este lugar:

    export SRC_DIR=`dirname $0`

    Update2:

    Su secuencia de comandos debe ser invocado directamente y no como bash /path/to/script.sh o source foo.sh. Añadir un el proceso de la línea de, añadir permisos de ejecución y la invocación de la secuencia de comandos directamente.

    • El problema en pwd es que se necesitaría el actual directorio desde donde ejecutar secuencias de comandos. así que podría ser en /tmp y ejecutar la secuencia de comandos anterior en /home/x/scripts, tomaría pwd /tmp. Pero realmente me gustaría ../ se van a resolver en relación a la ubicación del archivo de script. Por lo tanto la respuesta correcta para ../ debe ser /home/x/
    • Oh si quería una ruta de acceso relativa a la ubicación del archivo de script, debe especificar que en la pregunta! Ver respuesta actualizada.
    • dirname $0 da error, porque $0 se evalúa a la palabra -bash
    • Estás invocando la secuencia de comandos como bash /path/to/script.sh? Si es así, agregue #!/usr/bin/env bash como la primera línea de la secuencia de comandos y invocar el script directamente como /path/to/script.sh
    • estoy ejecutando como fuente de env.sh, donde env.sh contiene las variables
    • Esto tiene problema diferente, donde es necesario proporcionar el nombre completo de la ruta a la secuencia de comandos. Supongamos que yo estoy en el mismo directorio que el script y ejecutar este comando. La echo $LIBPATH ahora se muestran como ./lib. existe de todos modos a la fuerza . ampliar a la ruta completa del archivo?
    • Recibe el error con dirname $0 porque se está invocando como source foo.sh. Puede que desee probar lo que he mencionado en el Update2.

  5. 0

    Para mantener el código de error:

    function getPwd() {
        $(cd $1; [[ $? -ne 0 ]] && exit 1 || echo echo $PWD;)
        return $?
    }
    • Por favor, amplíe su respuesta: ¿por qué funciona? ¿Qué es la notación haciendo? Hay alguna documentación que a este?
  6. 0

    La excavación de este viejo hilo para añadir lo que he encontrado que funciona muy bien:

    exportación SRC_DIR = `realpath ..`

    ver más información aquí:

    http://man7.org/linux/man-pages/man3/realpath.3.html

    • Estoy downvoting esto porque se ha publicado sobre-y-otra vez aunque no sea una solución, porque realpath no es parte del estándar POSIX y por lo tanto no pueden ser tomadas en consideración en cada sistema.
    • Para la mayoría de los sistemas, es una mejor solución 😊

Dejar respuesta

Please enter your comment!
Please enter your name here