96 votes

Comment obtenir le répertoire absolu d'un fichier en bash ?

J'ai écrit un bash script qui prend un fichier d'entrée comme argument et le lit.
Ce fichier contient certains chemins (relatifs à son emplacement) vers des fichiers supplémentaires utilisés.

Je voudrais que le script aille dans le dossier contenant le fichier d'entrée, pour exécuter d'autres commandes.

Donc, comment obtenir le dossier (et seulement le dossier) à partir d'un fichier d'entrée ? (Dans linux.)

166voto

Chen Levy Points 4415

Pour obtenir le chemin complet, utilisez :

readlink -f relative/path/to/file

Pour obtenir le répertoire d'un fichier :

dirname relative/path/to/file

Vous pouvez également combiner les deux :

dirname $(readlink -f relative/path/to/file)

Si readlink -f n'est pas disponible sur votre système, vous pouvez utiliser cette option. * :

function myreadlink() {
  (
  cd "$(dirname $1)"         # or  cd "${1%/*}"
  echo "$PWD/$(basename $1)" # or  echo "$PWD/${1##*/}"
  )
}

Notez que si vous avez seulement besoin de vous déplacer vers un répertoire d'un fichier spécifié comme un chemin relatif, vous n'avez pas besoin de connaître le chemin absolu, un chemin relatif est parfaitement légal, donc utilisez simplement :

cd $(dirname relative/path/to/file)

si vous souhaitez revenir (pendant que le script est en cours d'exécution) au chemin d'origine, utilisez pushd au lieu de cd y popd lorsque vous avez terminé.


* Alors que myreadlink ci-dessus est suffisamment bonne dans le contexte de cette question, elle présente certaines limites par rapport à l'objectif de l'UE. readlink outil suggéré ci-dessus. Par exemple, il ne suit pas correctement un lien vers un fichier dont les caractéristiques sont différentes. basename .

23voto

Richard Sitze Points 5167

Jetez un coup d'œil à realpath qui est disponible sur GNU/Linux , FreeBSD y NetBSD mais pas OpenBSD 6.8. J'utilise quelque chose comme :

CONTAININGDIR=$(realpath ${FILEPATH%/*})

pour faire ce qu'on dirait que tu essaies de faire.

6voto

Jahid Points 12756

Cela fonctionne aussi bien pour les fichiers que pour les dossiers :

absPath(){
    if [[ -d "$1" ]]; then
        cd "$1"
        echo "$(pwd -P)"
    else 
        cd "$(dirname "$1")"
        echo "$(pwd -P)/$(basename "$1")"
    fi
}

5voto

Eugen Konkov Points 5218
$cat abs.sh
#!/bin/bash
echo "$(cd "$(dirname "$1")"; pwd -P)"

Quelques explications :

  1. Ce script reçoit un chemin relatif comme argument. "$1"
  2. Nous obtenons alors nom de répertoire de ce chemin (vous pouvez passer soit dir soit file à ce script) : dirname "$1"
  3. Alors nous cd "$(dirname "$1"); dans ce répertoire relatif
  4. pwd -P et obtenir le chemin absolu. Le site -P évitera les liens symboliques
  5. Comme étape finale, nous echo il

Ensuite, exécutez votre script :

abs.sh your_file.txt

1voto

AsymLabs Points 151

Essayez notre nouveau produit de bibliothèque Bash realpath-lib sur GitHub que nous avons donné à la communauté pour une utilisation libre et gratuite. Il est propre, simple et bien documenté, ce qui en fait un outil idéal pour apprendre. Vous pouvez le faire :

get_realpath <absolute|relative|symlink|local file path>

Cette fonction est le cœur de la bibliothèque :

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

}

Il utilise Bash 4+, ne nécessite aucune dépendance et fournit également get_dirname, get_filename, get_stemname et validate_path.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X