web-dev-qa-db-fra.com

Comment définir le répertoire de travail actuel dans le répertoire du script?

J'écris un script bash. J'ai besoin que le répertoire de travail actuel soit toujours le répertoire dans lequel se trouve le script.

Le comportement par défaut est que le répertoire de travail actuel du script est celui du shell à partir duquel je l'exécute, mais je ne souhaite pas ce comportement.

465
jameshfisher
#!/bin/bash
cd "$(dirname "$0")"
545
ndim

Ce qui suit fonctionne aussi:

cd "${0%/*}"

La syntaxe est décrite en détail dans this StackOverflow answer.

293
Paul Schulz

Essayez les lignes simples suivantes:


Pour tous les systèmes UNIX/OSX/Linux

dir=$(cd -P -- "$(dirname -- "$0")" && pwd -P)

Bash

dir=$(cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)

Remarque: un double tiret (-) est utilisé dans les commandes pour indiquer la fin des options de commande, de sorte que les fichiers contenant des tirets ou d'autres caractères spéciaux n'interrompent pas la commande.

Remarque: Dans Bash, utilisez ${BASH_SOURCE[0]} en faveur de $0, sinon le chemin peut être interrompu lors de son sourcing (source/.).


Pour Linux, Mac et autres * BSD:

cd "$(dirname "$(realpath "$0")")";

Remarque: realpath devrait être installé par défaut dans la distribution Linux la plus répandue (comme Ubuntu), mais dans certains cas, il peut être manquant et vous devez donc l'installer.

Remarque: Si vous utilisez Bash, utilisez ${BASH_SOURCE[0]} en faveur de $0, sinon le chemin peut être interrompu lors de la recherche de source (source/.).

Sinon, vous pourriez essayer quelque chose comme ça (le premier outil existant sera utilisé):

cd "$(dirname "$(readlink -f "$0" || realpath "$0")")"

Pour Linux spécifique:

cd "$(dirname "$(readlink -f "$0")")"

Utilisation de GNU readlink sur * BSD/Mac:

cd "$(dirname "$(greadlink -f "$0")")"

Remarque: vous devez avoir installé coreutils (par exemple, 1. Installez Homebrew , 2. brew install coreutils).


En bash

En bash, vous pouvez utiliser Parameter Expansions pour y parvenir, comme par exemple:

cd "${0%/*}"

mais cela ne fonctionne pas si le script est exécuté à partir du même répertoire.

Sinon, vous pouvez définir la fonction suivante dans bash:

realpath () {
  [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"
}

Cette fonction prend 1 argument. Si l'argument a déjà un chemin absolu, imprimez-le tel quel, sinon indiquez $PWD variable + argument de nom de fichier (sans le préfixe ./.).

ou voici la version extraite du fichier Debian .bashrc:

function realpath()
{
    f=$@
    if [ -d "$f" ]; then
        base=""
        dir="$f"
    else
        base="/$(basename "$f")"
        dir=$(dirname "$f")
    fi
    dir=$(cd "$dir" && /bin/pwd)
    echo "$dir$base"
}

Apparenté, relié, connexe:

Voir également:

Comment puis-je obtenir le comportement de readlink -f de GNU sur un Mac?

160
kenorb
cd "$(dirname "${BASH_SOURCE[0]}")"

C'est facile. Ça marche.

63
Dan Moulding

La réponse acceptée fonctionne bien pour les scripts qui n'ont pas été liés symboliquement ailleurs, comme dans $PATH.

#!/bin/bash
cd "$(dirname "$0")"

Cependant, si le script est exécuté via un lien symbolique,

ln -sv ~/project/script.sh ~/bin/; 
~/bin/script.sh

Cela ira dans le répertoire ~/bin/ et non dans le répertoire ~/project/, ce qui cassera probablement votre script si le but de la cd est d'inclure des dépendances relatives à ~/project/

La réponse sécurisée au lien symbolique est la suivante:

#!/bin/bash
cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")"

readlink -f est requis pour résoudre le chemin absolu du fichier potentiellement symlinked.

Les guillemets sont nécessaires pour prendre en charge les chemins de fichiers pouvant éventuellement contenir des espaces (mauvaise pratique, mais il n’est pas prudent de supposer que ce ne sera pas le cas)

5
James McGuigan

Ce script semble fonctionner pour moi:

#!/bin/bash
mypath=`realpath $0`
cd `dirname $mypath`
pwd

La ligne de commande pwd fait écho à l'emplacement du script en tant que répertoire de travail actuel, peu importe d'où je le lance.

2
Amardeep AC9MF

Obtenez le vrai chemin de votre script

if [ -L $0 ] ; then
    ME=$(readlink $0)
else
    ME=$0
fi
DIR=$(dirname $ME)

(Ceci est la réponse à la même question ici: Obtenez le nom du répertoire dans lequel un script est exécuté )

1
rodnower
cd "`dirname $(readlink -f ${0})`"
1
user742030