671 votes

Le shell Unix script permet de savoir dans quel répertoire réside le fichier script ?

En gros, j'ai besoin d'exécuter le script avec des chemins liés à l'emplacement du fichier du shell script, comment puis-je changer le répertoire actuel pour le même répertoire que celui où réside le fichier script ?

14 votes

S'agit-il vraiment d'un doublon ? Cette question concerne un "shell unix script", l'autre concerne spécifiquement Bash.

2 votes

@BoltClock : Cette question a été fermée de manière inappropriée. La question liée porte sur Bash. Cette question porte sur la programmation du shell Unix. Remarquez que les réponses acceptées sont très différentes !

0 votes

@Dietrich Epp : Vous avez raison. Il semble que le choix de la réponse acceptée par l'auteur de la question et l'ajout de la balise [bash] (probablement en réponse à cela) m'ont amené à marquer la question comme un doublon en réponse à un drapeau.

738voto

TheMarko Points 2630

Dans Bash, vous devriez obtenir ce dont vous avez besoin comme ça :

#!/usr/bin/env bash

BASEDIR=$(dirname "$0")
echo "$BASEDIR"

27 votes

Cela ne fonctionne pas si vous avez appelé le script via un lien symbolique dans un répertoire différent. Pour que cela fonctionne, vous devez utiliser readlink également (voir la réponse d'al ci-dessous)

59 votes

En bash, il est plus sûr d'utiliser $BASH_SOURCE à la place de $0 parce que $0 ne contient pas toujours le chemin du script invoqué, comme lors du 'sourcing' d'un script.

7 votes

$BASH_SOURCE est spécifique à Bash, la question porte sur le shell script en général.

499voto

al. Points 1211

Le message original contient la solution (ignorez les réponses, elles n'apportent rien d'utile). Le travail intéressant est effectué par la commande unix mentionnée ci-dessous readlink avec option -f . Fonctionne lorsque le script est appelé par un chemin absolu aussi bien que par un chemin relatif.

Pour bash, sh, ksh :

#!/bin/bash 
# Absolute path to this script, e.g. /home/user/bin/foo.sh
SCRIPT=$(readlink -f "$0")
# Absolute path this script is in, thus /home/user/bin
SCRIPTPATH=$(dirname "$SCRIPT")
echo $SCRIPTPATH

Pour tcsh, csh :

#!/bin/tcsh
# Absolute path to this script, e.g. /home/user/bin/foo.csh
set SCRIPT=`readlink -f "$0"`
# Absolute path this script is in, thus /home/user/bin
set SCRIPTPATH=`dirname "$SCRIPT"`
echo $SCRIPTPATH

Voir aussi : https://stackoverflow.com/a/246128/59087

0 votes

C'est le meilleur moyen. Notez que la réponse "cochée" ne fonctionnera pas si vous faites : ./myscript.sh ... cela indiquerait que le répertoire est "." - ceci vous donnera toujours le chemin absolu.

14 votes

Remarque : tous les systèmes ne disposent pas de readlink . C'est pourquoi j'ai recommandé d'utiliser pushd/popd (built-ins pour bash).

29 votes

Le site -f option pour readlink fait quelque chose de différent sur OS X (Lion) et éventuellement BSD. stackoverflow.com/questions/1055671/

55voto

Mez Points 9744

En supposant que vous utilisez bash

#!/bin/bash

current_dir=$(pwd)
script_dir=$(dirname "$0")

echo $current_dir
echo $script_dir

Ce script doit imprimer le répertoire dans lequel vous vous trouvez, puis le répertoire dans lequel se trouve le script. Par exemple, en l'appelant depuis / avec le script en /home/mez/ il produit

/
/home/mez

N'oubliez pas que lorsque vous assignez des variables à partir de la sortie d'une commande, enveloppez la commande dans le champ $( y ) - ou vous n'obtiendrez pas le résultat souhaité.

4 votes

Cela ne fonctionne pas lorsque j'invoque le script depuis le répertoire courant.

7 votes

@EricWang vous êtes toujours dans le répertoire courant.

1 votes

Pour moi, $current_dir est bien le chemin à partir duquel j'appelle le script. Cependant, $script_dir n'est pas le répertoire du script, c'est juste un point.

35voto

The Doctor What Points 4454

Si vous utilisez bash....

#!/bin/bash

pushd $(dirname "${0}") > /dev/null
basedir=$(pwd -L)
# Use "pwd -P" for the path without links. man bash for more info.
popd > /dev/null

echo "${basedir}"

4 votes

Vous pouvez remplacer le pushd / popd con cd $(dirname "${0}") y cd - pour le faire fonctionner sur d'autres coquilles, s'ils ont une pwd -L .

0 votes

Pourquoi utiliser pushd et popd ici ?

1 votes

Ainsi, je n'ai pas besoin de stocker le répertoire original dans une variable. C'est un modèle que j'utilise beaucoup dans les fonctions et autres. Il s'imbrique très bien, ce qui est bien.

23voto

ranamalo Points 71

Comme le suggère leMarko :

BASEDIR=$(dirname $0)
echo $BASEDIR

Cela fonctionne sauf si vous exécutez le script à partir du même répertoire où réside le script, auquel cas vous obtenez une valeur de '.'.

Pour contourner ce problème, utilisez :

current_dir=$(pwd)
script_dir=$(dirname $0)

if [ $script_dir = '.' ]
then
script_dir="$current_dir"
fi

Vous pouvez maintenant utiliser la variable current_dir tout au long de votre script pour faire référence au répertoire script. Cependant, cela peut encore avoir le problème de lien symbolique.

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