Vérifier si un répertoire existe dans un script shell

quelle commande peut être utilisée pour vérifier si un répertoire existe ou non, dans un script shell?

3088
demandé sur Jahid 2008-09-13 00:06:25

30 réponses

pour vérifier si un répertoire existe dans un script shell, vous pouvez utiliser ce qui suit:

if [ -d "$DIRECTORY" ]; then
  # Control will enter here if $DIRECTORY exists.
fi

ou pour vérifier si un répertoire n'existe pas:

if [ ! -d "$DIRECTORY" ]; then
  # Control will enter here if $DIRECTORY doesn't exist.
fi

cependant, comme le souligne Jon Ericson , les commandes subséquentes peuvent ne pas fonctionner comme prévu si vous ne tenez pas compte du fait qu'un lien symbolique vers un répertoire passera également cette vérification. Par exemple:

ln -s "$ACTUAL_DIR" "$SYMLINK"
if [ -d "$SYMLINK" ]; then 
  rmdir "$SYMLINK" 
fi

produira le message d'erreur:

rmdir: failed to remove `symlink': Not a directory

ainsi les liens symboliques peuvent devoir être traités différemment, si les commandes suivantes attendent des répertoires:

if [ -d "$LINK_OR_DIR" ]; then 
  if [ -L "$LINK_OR_DIR" ]; then
    # It is a symlink!
    # Symbolic link specific commands go here.
    rm "$LINK_OR_DIR"
  else
    # It's a directory!
    # Directory command goes here.
    rmdir "$LINK_OR_DIR"
  fi
fi

prenez particulièrement note des doubles guillemets utilisés pour envelopper les variables, la raison en est expliquée par 8jean dans une autre réponse .

Si les variables contiennent des espaces ou d'autres caractères inhabituels cela causera probablement l'échec du script.

4272
répondu Grundlefleck 2018-06-20 11:23:27

N'oubliez pas de toujours envelopper les variables dans des guillemets doubles lorsque vous les référencez en un scénario de bash. Les jeunes d'aujourd'hui grandissent avec l'idée qu'ils puissent avoir des espaces et beaucoup d'autres drôles de personnages dans leurs noms de répertoire. (Espaces! De retour dans mes jours, nous n'avions pas de fantaisie, des espaces! ;))

un jour, un de ces enfants exécutera votre script avec $DIRECTORY réglé sur "My M0viez" et votre script explosera. Vous ne voulez pas que. Afin d'utiliser cette.

if [ -d "$DIRECTORY" ]; then
    # Will enter here if $DIRECTORY exists, even if it contains spaces
fi
464
répondu 8jean 2017-05-11 07:08:53

Note le test - d peut donner des résultats surprenants:

$ ln -s tmp/ t
$ if [ -d t ]; then rmdir t; fi
rmdir: directory "t": Path component not a directory

Fichier sous: "Quand est-ce un répertoire n'est pas un répertoire?"La réponse: "Quand c'est un lien symbolique vers un répertoire."Un peu plus approfondie de test:

if [ -d t ]; then 
   if [ -L t ]; then 
      rm t
   else 
      rmdir t
   fi
fi

, Vous pouvez trouver plus d'informations dans le manuel de Bash sur Bash expressions conditionnelles et le [ builtin commande et le [[ composé de commande .

208
répondu Jon Ericson 2017-09-11 14:10:31

je trouve que la double-crochet version de test rend l'écriture de la logique des tests plus naturel:

if [[ -d "${DIRECTORY}" && ! -L "${DIRECTORY}" ]] ; then
    echo "It's a bona-fide directory"
fi
200
répondu yukondude 2013-07-01 01:56:50

forme Courte:

[ -d "$DIR" ] && echo "Yes"
130
répondu elmarco 2015-05-25 13:13:44

pour vérifier si un répertoire existe, Vous pouvez utiliser simple if structure comme ceci:

if [ -d directory/path to a directory ] ; then
#Things to do

else #if needed #also: elif [new condition] 
# things to do
fi

Vous pouvez le faire aussi en négatif

if [ ! -d directory/path to a directory ] ; then
# things to do when not an existing directory

Note : attention, laisser des espaces vides de chaque côté des entretoises d'ouverture et de fermeture.

Avec la même syntaxe que vous pouvez utiliser:

-e: any kind of archive 

-f: file 

-h: symbolic link 

-r: readable file 

-w: writable file 

-x: executable file 

-s: file size greater than zero 
119
répondu Jorge Barroso 2015-07-23 22:28:05
if [ -d "$DIRECTORY" ]; then  
    # Here if $DIRECTORY exists  
fi
94
répondu Ayyappa Boligala 2017-08-01 01:01:00

vous pouvez utiliser test -d (voir man test ).

-d file True si le fichier existe et est un répertoire.

par exemple:

test -d "/etc" && echo Exists || echo Does not exist

Note: la commande test est la même que l'expression conditionnelle [ (voir: man [ ), donc elle est portable à travers les scripts shell.

[ - c'est un synonyme de test builtin, mais le dernier argument doit être un littéral ] , pour correspondre à l'ouverture [ .

pour les options possibles ou une aide supplémentaire, cochez:

  • help [
  • help test
  • man test ou man [
77
répondu kenorb 2016-03-16 17:01:20

ou pour quelque chose de complètement inutile:

[ -d . ] || echo "No"
54
répondu sth 2009-08-17 15:47:53

voici un idiome très pragmatique:

(cd $dir) || return # is this a directory,
                    # and do we have access?

Je l'enroule généralement dans une fonction:

can_use_as_dir() { 
    (cd ${1:?pathname expected}) || return
}

ou:

assert_dir_access() { 
    (cd ${1:?pathname expected}) || exit
}

ce qui est bien avec cette approche, c'est que je n'ai pas besoin de penser à un bon message d'erreur.

cd me donnera déjà un message standard d'une ligne à stderr. Il fournira également plus d'informations que je ne pourrai fournir. En effectuant les cd à l'intérieur d'une sous-cellule ( ... ) , la commande n'affecte pas le répertoire courant de l'appelant. Si le répertoire existe, ce subshell et la fonction ne sont qu'une No-op.

est Ensuite l'argument que l'on passe à cd : ${1:?pathname expected} . C'est une forme plus élaborée de substitution de paramètres qui est expliqué plus en détail ci-dessous.

Tl; dr: si la chaîne passée dans cette fonction est vide, nous sortons de nouveau de la cellule ( ... ) et revenir de la fonction avec le message d'erreur donné.


citant la ksh93 man page:

${parameter:?word}

si parameter est défini et est non-null alors substituer sa valeur; sinon, Imprimez word et sortez du shell (si non interactif). Si word est omis, alors un message est imprimé.

et

si le point : est omis des expressions ci-dessus, alors le shell vérifie seulement si le paramètre est réglé ou pas.

la formulation ici est particulière à la documentation shell, comme word peut se référer pour toute raisonnable chaîne, y compris les espaces.

Dans ce cas particulier, je sais que le message d'erreur standard 1: parameter not set n'est pas suffisant, donc je zoom sur le type de valeur qui nous attend ici - le pathname d'un répertoire.

Une remarque philosophique: Le shell n'est pas un langage orienté objet, donc le message dit pathname , pas directory . A ce niveau, je préfère rester simple - les arguments d'une fonction ne sont que des chaînes.

46
répondu Henk Langeveld 2014-02-16 12:00:18
if [ -d "$Directory" -a -w "$Directory" ]
then
    #Statements
fi

le code ci-dessus vérifie si le répertoire existe et s'il est accessible en écriture.

35
répondu muralikrishna 2011-05-25 08:51:12
  1. Un script simple pour tester si dir ou le fichier est présent ou non:

    if [ -d /home/ram/dir ]   # for file "if [-f /home/rama/file]" 
    then 
        echo "dir present"
    else
        echo "dir not present"
    fi
    
  2. un script simple pour vérifier si le répertoire est présent ou non:

    mkdir tempdir   # if you want to check file use touch instead of mkdir
    ret=$?
    if [ "$ret" == "0" ]
    then
        echo "dir present"
    else
        echo "dir not present"
    fi
    

    les scripts ci-dessus vérifieront que le dir est présent ou non

    $? si la dernière commande réussit elle renvoie " 0 " sinon Non valeur zéro. supposons que tempdir soit déjà présent alors mkdir tempdir sera donnez l'erreur comme ci-dessous:

    mkdir: ne peut créer le répertoire ‘rep’: le Fichier existe déjà

28
répondu siva 2018-07-18 15:18:44

tapez ce code sur le bash promt

if [ -d "$DIRECTORY" ]; then
  # if true this block of code will execute
fi
24
répondu santosh 2014-11-05 03:39:01

autres caractéristiques utilisant find

  • vérifier l'existence du dossier dans les sous-répertoires:

    found=`find -type d -name "myDirectory"`
    if [ -n "$found"]
    then
        # The variable 'found' contains the full path where "myDirectory" is.
        # It may contain several lines if there are several folders named "myDirectory".
    fi
    
  • vérifier l'existence d'un ou plusieurs dossiers basés sur un motif dans le répertoire courant:

    found=`find -maxdepth 1 -type d -name "my*"`
    if [ -n "$found"]
    then
        # The variable 'found' contains the full path where folders "my*" have been found.
    fi
    
  • les deux combinaisons. Dans l'exemple suivant, il vérifie l'existence du dossier dans le répertoire courant:

    found=`find -maxdepth 1 -type d -name "myDirectory"`
    if [ -n "$found"]
    then
        # The variable 'found' is not empty => "myDirectory"` exists.
    fi
    
20
répondu Neil Neyman 2014-10-10 10:49:39

en fait, vous devriez utiliser plusieurs outils pour obtenir une approche à l'épreuve des balles:

DIR_PATH=`readlink -f "${the_stuff_you_test}"` # Get rid of symlinks and get abs path
if [[ -d "${DIR_PATH}" ]] ; Then # now you're testing
    echo "It's a dir";
fi

pas besoin de vous soucier des espaces et des caractères spéciaux si vous utilisez "${}" .

notez que [[]] n'est pas aussi portable que [] , mais puisque la plupart des gens travaillent avec des versions modernes de Bash (car après tout, la plupart des gens ne travaillent même pas avec la ligne de commande :-p), l'avantage est plus grand que la difficulté.

19
répondu e-satis 2013-09-22 08:33:54

pour vérifier plus d'un répertoire, utilisez ce code:

if [ -d "$DIRECTORY1" ] && [ -d "$DIRECTORY2" ] then
    # Things to do
fi
16
répondu Raamesh Keerthi 2016-01-27 13:02:41

Avez-vous envisagé de faire ce que vous voulez faire dans le if plutôt que de regarder avant de vous lancer?

IE, si vous voulez vérifier l'existence d'un répertoire avant de l'entrer, essayez juste de faire ceci:

if pushd /path/you/want/to/enter; then
    # commands you want to run in this directory
    popd
fi

si le chemin que vous donnez à pushd existe, vous l'entrerez et il sortira avec 0 , ce qui signifie que la partie then de la déclaration s'exécutera. S'il n'existe pas, rien n' va se produire (autre qu'une sortie disant que le répertoire n'existe pas, ce qui est probablement un effet secondaire utile de toute façon pour le débogage).

semble mieux que cela, ce qui nécessite de se répéter:

if [ -d /path/you/want/to/enter ]; then
    pushd /path/you/want/to/enter
    # commands you want to run in this directory
    popd
fi

même chose fonctionne avec cd , mv , rm , etc... si vous essayez sur les fichiers qui n'existent pas, ils vont sortir avec une erreur et imprimer un message disant qu'il n'existe pas, et votre then bloc sera sauter. Si vous les Essayez sur des fichiers qui existent, la commande exécutera et sortira avec un statut 0 , permettant à votre bloc then de s'exécuter.

15
répondu ArtOfWarfare 2017-12-07 16:24:23
[[ -d "$DIR" && ! -L "$DIR" ]] && echo "It's a directory and not a symbolic link"

N. B: citer des variables est une bonne pratique.

14
répondu Jahid 2015-05-20 04:20:51

vérifiez si le répertoire existe, sinon faites-en un

[ -d "$DIRECTORY" ] || mkdir $DIRECTORY
14
répondu David Okwii 2016-03-23 07:25:55
[ -d ~/Desktop/TEMPORAL/ ] && echo "DIRECTORY EXISTS" || echo "DIRECTORY DOES NOT EXIST"
12
répondu Juan Carlos Kuri Pinto 2013-07-28 08:36:06

Cette réponse enveloppé comme un script shell

exemples

$ is_dir ~                           
YES

$ is_dir /tmp                        
YES

$ is_dir ~/bin                       
YES

$ mkdir '/tmp/test me'

$ is_dir '/tmp/test me'
YES

$ is_dir /asdf/asdf                  
NO

# Example of calling it in another script
DIR=~/mydata
if [ $(is_dir $DIR) == "NO" ]
then
  echo "Folder doesnt exist: $DIR";
  exit;
fi

is_dir

function show_help()
{
  IT=$(CAT <<EOF

  usage: DIR
  output: YES or NO, depending on whether or not the directory exists.

  )
  echo "$IT"
  exit
}

if [ "" == "help" ]
then
  show_help
fi
if [ -z "" ]
then
  show_help
fi

DIR=
if [ -d $DIR ]; then 
   echo "YES";
   exit;
fi
echo "NO";
11
répondu Brad Parks 2017-05-23 12:26:36

en utilisant le contrôle -e vérifiera les fichiers et cela inclut les répertoires.

if [ -e ${FILE_PATH_AND_NAME} ]
then
    echo "The file or directory exists."
fi
9
répondu bailey86 2013-07-28 08:34:29

Que par Jonathan commentaire:

si vous voulez créer le répertoire et qu'il n'existe pas encore, alors la technique la plus simple est d'utiliser mkdir -p qui crée le répertoire - et tous les répertoires manquants en haut du chemin - et n'échoue pas si le répertoire existe déjà, donc vous pouvez le faire tout à la fois avec:

mkdir -p /some/directory/you/want/to/exist || exit 1
8
répondu kenorb 2017-05-23 10:31:37
if [ -d "$DIRECTORY" ]; then
    # Will enter here if $DIRECTORY exists
fi

Ce n'est pas tout à fait vrai... Si vous voulez aller dans ce répertoire, vous avez également besoin d'avoir les droits d'exécution sur le répertoire. Peut-être que vous devez avoir les droits en écriture.

donc:

if [ -d "$DIRECTORY" ] && [ -x "$DIRECTORY" ] ; then
    # ... to go to that directory (even if DIRECTORY is a link)
    cd $DIRECTORY
    pwd
fi

if [ -d "$DIRECTORY" ] && [ -w "$DIRECTORY" ] ; then
    # ... to go to that directory and write something there (even if DIRECTORY is a link)
    cd $DIRECTORY
    touch foobar
fi
7
répondu 2010-03-18 10:52:57

la commande ls en conjonction avec -l (liste longue) l'option renvoie des attributs informations sur les fichiers et répertoires.

En particulier le premier caractère de ls -l sortie il est généralement un d ou un - (tiret). Dans le cas d'un d est un répertoire pour vous.

la commande suivante en une seule ligne vous dira si la donnée ISDIR variable contient un chemin d'accès à un répertoire ou non:

[[ $(ls -ld "$ISDIR" | cut -c1) == 'd' ]] &&
    echo "YES, $ISDIR is a directory." || 
    echo "Sorry, $ISDIR is not a directory"

usage pratique:

    [claudio@nowhere ~]$ ISDIR="$HOME/Music" 
    [claudio@nowhere ~]$ ls -ld "$ISDIR"
    drwxr-xr-x. 2 claudio claudio 4096 Aug 23 00:02 /home/claudio/Music
    [claudio@nowhere ~]$ [[ $(ls -ld "$ISDIR" | cut -c1) == 'd' ]] && 
        echo "YES, $ISDIR is a directory." ||
        echo "Sorry, $ISDIR is not a directory"
    YES, /home/claudio/Music is a directory.

    [claudio@nowhere ~]$ touch "empty file.txt"
    [claudio@nowhere ~]$ ISDIR="$HOME/empty file.txt" 
    [claudio@nowhere ~]$ [[ $(ls -ld "$ISDIR" | cut -c1) == 'd' ]] && 
        echo "YES, $ISDIR is a directory." || 
        echo "Sorry, $ISDIR is not a directoy"
    Sorry, /home/claudio/empty file.txt is not a directory
6
répondu ztank1013 2014-02-26 11:21:39
file="foo" 
if [[ -e "$file" ]]; then echo "File Exists"; fi;
5
répondu ajmartin 2013-02-22 02:39:07

si vous voulez vérifier si un répertoire existe, qu'il s'agisse d'un répertoire réel ou d'un lien symbolique, utilisez ceci:

ls $DIR
if [ $? != 0 ]; then
        echo "Directory $DIR already exists!"
        exit 1;
fi
echo "Directory $DIR does not exist..."

Explication: Le "ls" commande donne une erreur "ls: /x: Aucun fichier ou répertoire" si le répertoire ou le lien symbolique n'existe pas, et définit également le code de retour, vous pouvez le récupérer via "$?", à non-null (normalement"1"). Assurez-vous de vérifier le code de retour directement après avoir appelé "ls".

5
répondu derFunk 2014-01-08 10:38:41

(1)

[ -d Piyush_Drv1 ] && echo ""Exists"" || echo "Not Exists"

(2)

[ `find . -type d -name Piyush_Drv1 -print | wc -l` -eq 1 ] && echo Exists || echo "Not Exists"

(3)

[[ -d run_dir  && ! -L run_dir ]] && echo Exists || echo "Not Exists"

S'il y a un problème avec l'une des approches prévues ci-dessus.

avec la commande ls ; les cas où le répertoire n'existe pas - un message d'erreur est affiché

$ [[ ls -ld SAMPLE_DIR| grep ^d | wc -l -EQ 1 ]] && echo existe || n'existe pas -ksh: non: pas trouvé [Aucun fichier ou répertoire]

5
répondu Piyush Baijal 2015-05-13 07:38:37

bonnes solutions là-bas, mais finalement chaque script échouera si vous n'êtes pas dans le bon répertoire. Alors code comme ceci:

if [ -d "$LINK_OR_DIR" ]; then 
if [ -L "$LINK_OR_DIR" ]; then
    # It is a symlink!
    # Symbolic link specific commands go here
    rm "$LINK_OR_DIR"
else
    # It's a directory!
    # Directory command goes here
    rmdir "$LINK_OR_DIR"
fi
fi

n'exécutera avec succès que si au moment de l'exécution vous êtes dans un répertoire qui a un sous-répertoire que vous vous trouvez à vérifier.

je comprends la question initiale, comme ceci: pour vérifier si un répertoire existe indépendamment de la position de l'utilisateur dans le système de fichiers. Donc, en utilisant la commande "trouver" pourrait faire l'affaire:

dir=" "
echo "Input directory name to search for:"
read dir
find $HOME -name $dir -type d

cette solution est bonne car elle permet l'utilisation de caractères génériques, une fonctionnalité utile lors de la recherche de fichiers/répertoires. Le seul problème est que, si le répertoire recherché n'existe pas, la commande "find" n'imprimera rien à stdout (pas une solution élégante à mon goût) et aura néanmoins une sortie zéro. Peut-être que quelqu'un pourrait améliorer ça.

4
répondu dromichaetes 2011-12-12 21:46:29

ci-dessous find peut être utilisé,

find . -type d -name dirname -prune -print
4
répondu Sadhun 2014-08-13 13:41:35