Question

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

Était-ce utile?

La solution

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 Jon Ericson le souligne, les commandes suivantes 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.en exécutant ceci :

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 devront peut-être ê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

Faites particulièrement attention aux 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, le script échouera probablement.

Autres conseils

N'oubliez pas de toujours envelopper les variables en doubles citations lorsque vous les référez dans un script bash.Les enfants d’aujourd’hui grandissent avec l’idée qu’ils peuvent avoir des espaces et de nombreux autres caractères amusants dans les noms de leurs répertoires.(Les espaces!À mon époque, nous n’avions pas d’espaces chics !;))

Un jour, un de ces enfants exécutera votre script avec $DIRECTORY mis à "My M0viez" et votre script va exploser.Vous ne voulez pas ça.Alors utilisez ceci.

if [ -d "$DIRECTORY" ]; then
    # Will enter here if $DIRECTORY exists, even if it contains spaces
fi

Noter la -d Le test peut produire des résultats surprenants :

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

Classer sous :"Quand un répertoire n'est-il pas un répertoire?" La réponse:"Quand c'est un lien symbolique pour un répertoire." Un test légèrement plus approfondi:

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

Vous pouvez trouver plus d'informations dans le manuel Bash sur Bash expressions conditionnelles et le [ commande intégrée et le [[ commande composée.

je trouve le double support version de test rend l'écriture de tests logiques plus naturelle :

if [[ -d "${DIRECTORY}" && ! -L "${DIRECTORY}" ]] ; then
    echo "It's a bona-fide directory"
fi

Forme plus courte :

[ -d "$DIR" ] && echo "Yes"

Pour vérifier si un répertoire existe, vous pouvez utiliser une structure if simple comme celle-ci :

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, laissez des espaces vides de chaque côté des accolades d'ouverture et de fermeture.

Avec la même syntaxe, 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 
if [ -d "$DIRECTORY" ]; then  
    # Here if $DIRECTORY exists  
fi

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

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

Par exemple:

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

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

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

Pour connaître les options possibles ou une aide supplémentaire, consultez :

  • help [
  • help test
  • man test ou man [
  1. Un script simple pour tester si le répertoire 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 répertoire est présent ou non

    $? si la dernière commande réussit, elle renvoie "0", sinon valeur non nulle.supposer tempdir est déjà présent alors mkdir tempdir donnera une erreur comme ci-dessous:

    répertoire mk :impossible de créer le répertoire « tempdir » :le fichier existe

Ou pour quelque chose de complètement inutile :

[ -d . ] || echo "No"

Voici un idiome très pragmatique :

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

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

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

Ou:

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

L’avantage de cette approche 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.Cela donnera également plus d’informations que je ne pourrai en fournir.En effectuant le cd à l'intérieur d'un sous-shell ( ... ), la commande n'affecte pas le répertoire courant de l'appelant.Si le répertoire existe, ce sous-shell et la fonction ne sont qu'un non-op.

Vient ensuite l’argument que nous passons à cd: ${1:?pathname expected}.Il s'agit d'une forme plus élaborée de substitution de paramètres qui est expliquée plus en détail ci-dessous.

Tl;dr :Si la chaîne passée dans cette fonction est vide, on sort à nouveau du sous-shell ( ... ) et revenez de la fonction avec le message d'erreur donné.


Citant le ksh93 page de manuel :

${parameter:?word}

Si parameter est défini et n'est pas nul, puis remplacez sa valeur ;sinon, imprimez word et quittez le shell (s'il n'est pas interactif).Si word est omis, un message standard est imprimé.

et

Si le côlon : est omis des expressions ci-dessus, puis le shell vérifie uniquement si le paramètre est défini ou non.

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

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

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

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.

Tapez ce code sur l'invite bash

if [ -d "$DIRECTORY" ]; then
  # if true this block of code will execute
fi

Plus de fonctionnalités en utilisant find

  • Vérifiez 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érifiez l'existence d'un ou plusieurs dossiers en fonction d'un modèle au sein du 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
    

En fait, vous devez utiliser plusieurs outils pour obtenir une approche à toute épreuve :

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 tant que vous utilisez "${}".

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

Pour vérifier plusieurs répertoires, utilisez ce code :

if [ -d "$DIRECTORY1" ] && [ -d "$DIRECTORY2" ] then
    # Things to do
fi

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 souhaitez vérifier l'existence d'un répertoire avant d'y accéder, essayez simplement ceci :

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

Si le chemin que tu donnes à pushd existe, vous y entrerez et il sortira avec 0, ce qui signifie le then Une partie de l'instruction sera exécutée.S'il n'existe pas, rien ne se passera (à part une sortie indiquant que le répertoire n'existe pas, ce qui est probablement de toute façon un effet secondaire utile pour le débogage).

Cela 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

La même chose fonctionne avec cd, mv, rm, etc...si vous les essayez sur des fichiers qui n'existent pas, ils se fermeront avec une erreur et imprimeront un message indiquant qu'ils n'existent pas, et votre then le bloc sera ignoré.Si vous les essayez sur des fichiers qui existent, la commande s'exécutera et se terminera avec un statut de 0, permettant à votre then bloc à exécuter.

Vérifiez si le répertoire existe, sinon créez-en un

[ -d "$DIRECTORY" ] || mkdir $DIRECTORY
[[ -d "$DIR" && ! -L "$DIR" ]] && echo "It's a directory and not a symbolic link"

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

[ -d ~/Desktop/TEMPORAL/ ] && echo "DIRECTORY EXISTS" || echo "DIRECTORY DOES NOT EXIST"

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 [ "$1" == "help" ]
then
  show_help
fi
if [ -z "$1" ]
then
  show_help
fi

DIR=$1
if [ -d $DIR ]; then 
   echo "YES";
   exit;
fi
echo "NO";

En utilisant le -e check vérifiera les fichiers et cela inclut les répertoires.

if [ -e ${FILE_PATH_AND_NAME} ]
then
    echo "The file or directory exists."
fi

Selon Jonathan commentaire:

Si vous souhaitez 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 sur le chemin — et n'échoue pas si le répertoire existe déjà, vous pouvez donc tout faire en même temps avec :

mkdir -p /some/directory/you/want/to/exist || exit 1
if [ -d "$DIRECTORY" ]; then
    # Will enter here if $DIRECTORY exists
fi

Ce n'est pas tout à fait vrai...Si vous souhaitez accéder à ce répertoire, vous devez également disposer des droits d'exécution sur le répertoire.Peut-être que vous devez également disposer de droits d'écriture.

Par conséquent :

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

Le ls commande en conjonction avec -l (liste longue) renvoie des informations sur les attributs des fichiers et des répertoires.
En particulier le premier personnage de ls -l sortie, c'est généralement un d ou un - (tiret).Dans le cas d'un d celui répertorié est certainement un répertoire.

La commande suivante en une seule ligne vous dira si le ISDIR La variable contient ou non un chemin vers un répertoire :

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

Utilisation 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
file="foo" 
if [[ -e "$file" ]]; then echo "File Exists"; fi;

Si vous souhaitez vérifier si un répertoire existe, qu'il s'agisse d'un vrai répertoire 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:La commande "ls" donne une erreur "ls :/X:Aucun fichier ou répertoire de ce type" si le répertoire ou le lien symbolique n'existe pas, et définit également le code de retour, que vous pouvez récupérer via "$?", sur non nul (normalement "1").Assurez-vous de vérifier le code retour directement après avoir appelé "ls".

(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"

Si vous rencontrez un problème avec l’une des approches fournies ci-dessus.

Avec ls commande;les cas où le répertoire n'existe pas - un message d'erreur s'affiche

$ [[ ls -ld SAMPLE_DIR| grep ^d | wc -l -eq 1]] && echo existe || ne pas existe -ksh:pas:introuvable [Aucun fichier ou répertoire de ce type]

D'excellentes solutions existent, mais en fin de compte, chaque script échouera si vous n'êtes pas dans le bon répertoire.Donc codez 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

ne s'exécutera avec succès que si, au moment de l'exécution, vous vous trouvez dans un répertoire contenant un sous-répertoire que vous recherchez.

Je comprends la question initiale comme ceci :pour vérifier si un répertoire existe quelle que soit la position de l'utilisateur dans le système de fichiers.Donc, utiliser la commande « find » pourrait faire l'affaire :

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

Cette solution est intéressante 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 sur la sortie standard (ce qui n'est pas une solution élégante à mon goût) et aura néanmoins une sortie nulle.Peut-être que quelqu'un pourrait améliorer cela.

La recherche ci-dessous peut être utilisée,

find . -type d -name dirname -prune -print
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top