He escrito un script bash que toma un archivo de entrada como argumento y lo lee.
Este archivo contiene algunas rutas (relativas a su ubicación) a archivos adicionales utilizados.
Me gustaría que el script vaya a la carpeta que contiene el archivo de entrada para ejecutar más comandos.
Entonces, ¿cómo obtengo la carpeta (y solo la carpeta) de un archivo de entrada? (En linux.)

Respuestas:
Para obtener el uso de la ruta completa:
Para obtener el directorio de un archivo:
También puedes combinar los dos:
Si
readlink -fno está disponible en su sistema, puede usar esto * :function myreadlink() { ( cd "$(dirname $1)" # or cd "${1%/*}" echo "$PWD/$(basename $1)" # or echo "$PWD/${1##*/}" ) }Tenga en cuenta que si solo necesita moverse a un directorio de un archivo especificado como una ruta relativa, no necesita saber la ruta absoluta, una ruta relativa es perfectamente legal, así que use:
cd $(dirname relative/path/to/file)si desea volver (mientras se ejecuta el script) a la ruta original, utilice en
pushdlugar decdypopdcuando haya terminado.* Si bien lo
myreadlinkanterior es suficientemente bueno en el contexto de esta pregunta, tiene algunas limitaciones en relación con lareadlinkherramienta sugerida anteriormente. Por ejemplo, no sigue correctamente un enlace a un archivo con diferentebasename.fuente
readlink -f, lamentablemente, no funciona en OS X.brew install coreutilsconseguirlo. stackoverflow.com/a/4031502/1022967 .${1%/*}o${1##*/}como sustitutos dedirnameybasename. El primero se rompe si le da un nombre de archivo simple (dirname foo.barsería, correctamente, ser.), y el segundo se rompe para un directorio que termina con una barra (basename /foo/bar/, correctamente, seríabar).basename/dirnameno son incorporados), y lo verán funcionando al principio, pero de repente se romperá en algún momento en el futuro por aparentemente no ser bueno razón. Evitaría sugerirlo como una opción, o negaría que realmente no sea un sustituto a prueba de balas.Eche un vistazo a la página de manual de
realpath, yo uso eso y algo como:para hacer lo que parece que estás intentando hacer.
fuente
Esto funcionará tanto para el archivo como para la carpeta:
absPath(){ if [[ -d "$1" ]]; then cd "$1" echo "$(pwd -P)" else cd "$(dirname "$1")" echo "$(pwd -P)/$(basename "$1")" fi }fuente
$cat abs.sh #!/bin/bash echo "$(cd "$(dirname "$1")"; pwd -P)"Algunas explicaciones:
"$1"dirname "$1"cd "$(dirname "$1");en este directorio relativopwd -Py obtener la ruta absoluta. La-Popción evitará los enlaces simbólicosecholoLuego ejecuta tu script:
fuente
Pruebe nuestro nuevo producto de biblioteca Bash, realpath-lib, en GitHub, que le hemos proporcionado a la comunidad de forma gratuita y sin obstáculos. Es limpio, simple y bien documentado, por lo que es genial aprender de él. Tu puedes hacer:
get_realpath <absolute|relative|symlink|local file path>Esta función es el núcleo de la biblioteca:
if [[ -f "$1" ]] then # file *must* exist if cd "$(echo "${1%/*}")" &>/dev/null then # file *may* not be local # exception is ./file.ext # try 'cd .; cd -;' *works!* local tmppwd="$PWD" cd - &>/dev/null else # file *must* be local local tmppwd="$PWD" fi else # file *cannot* exist return 1 # failure fi # reassemble realpath echo "$tmppwd"/"${1##*/}" return 0 # success }Es Bash 4+, no requiere ninguna dependencia y también proporciona get_dirname, get_filename, get_stemname y validate_path.
fuente
El problema con la respuesta anterior viene con la entrada de archivos con "./" como "./my-file.txt"
Solución alternativa (de muchas):
myfile="./somefile.txt" FOLDER="$(dirname $(readlink -f "${ARG}"))" echo ${FOLDER}fuente
He estado usando readlink -f funciona en linux
entonces
FULL_PATH=$(readlink -f filename) DIR=$(dirname $FULL_PATH) PWD=$(pwd) cd $DIR #<do more work> cd $PWDfuente
PWDya existe en Bash y su valor es en realidad el directorio actual? Y use más citas también.