Comment puis-je vérifier si un répertoire existe dans un script shell Bash?

3726

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

Grundlefleck
la source

Réponses:

5151

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 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, exécuter 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 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 guillemets doubles utilisés pour encapsuler 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.

Grundlefleck
la source
29
Si vous voulez jouer en toute sécurité avec les outils GNU, l'utilisation de --est fortement recommandée (marqueur de fin d'options). Sinon, si votre variable contient quelque chose qui ressemble à une option, le script échouera comme avec les espaces.
Marc Mutz - mmutz
2
Pour les versions modernes de bash, ksh, etc. est un [...] intégré
fpmurphy
79
Une chose à garder à l'esprit: [ ! -d "$DIRECTORY" ]sera vraie soit si elle $DIRECTORYn'existe pas, soit si elle existe mais n'est pas un répertoire. Considérez quelque chose comme if [ ! -d "$DIRECTORY" ] ; then mkdir "$DIRECTORY" ; fi; cela échouera s'il "$DIRECTORY"s'agit d'un fichier. (Bien sûr, vous devriez vérifier si cela a mkdirréussi de toute façon; il y a un certain nombre de raisons pour lesquelles cela peut échouer.)
Keith Thompson
5
Il peut être utile de mentionner que dès que le contrôle a été effectué, la situation peut déjà avoir changé en raison d'autres processus. Dans de nombreux cas, il est préférable de simplement créer ou utiliser le répertoire et de réagir en cas d'échec.
Alfe
12
Au lieu de tester à la fois le répertoire ( -d) et le lien symbolique ( -L), il est plus facile d'ajouter simplement une barre oblique à la variable, comme if [ -d "${THING:+$THING/}" ]. Un répertoire ne se souciera pas de la barre oblique supplémentaire. Un fichier sera évalué à faux. Vide restera vide, donc faux. Et un lien symbolique sera résolu vers sa destination. Bien sûr, cela dépend de votre objectif. Si vous voulez y aller , ça va. Si vous souhaitez le supprimer , le code de cette réponse est préférable.
ghoti
531

N'oubliez pas de toujours encapsuler les variables entre guillemets lorsque vous les référencez dans un script Bash. Les enfants grandissent de nos jours avec l'idée qu'ils peuvent avoir des espaces et beaucoup d'autres personnages amusants dans leurs noms de répertoire. (Espaces! À l'époque, nous n'avions pas d'espaces fantaisistes!;))

Un jour, l'un de ces enfants exécutera votre script avec $DIRECTORYset to "My M0viez"et votre script explosera. Tu ne veux pas ça. Alors utilisez ça.

if [ -d "$DIRECTORY" ]; then
    # Will enter here if $DIRECTORY exists, even if it contains spaces
fi
8jean
la source
9
Une autre raison d'utiliser des guillemets doubles est au cas où $ DIRECTORY n'est pas défini pour une raison quelconque.
Jon Ericson
2
"toujours envelopper les variables entre guillemets ... dans un script bash." Pour bash, pas techniquement nécessaire lors de l'utilisation de [[...]]; voir tldp.org/LDP/abs/html/testconstructs.html#DBLBRACKETS (note: pas de division de mot): "Aucune expansion de nom de fichier ou division de mot n'a lieu entre [[et]], mais il y a expansion de paramètre et substitution de commande."
michael
2
Les répertoires sous Unix / Linux ne devraient pas avoir d'espaces, et par conséquent les scripts ne devraient pas y être adaptés. C'est déjà assez mal Windows le prend en charge, avec toutes les conséquences pour les scripts Windows, mais s'il vous plaît, pour l'amour de quoi que ce soit, pas besoin d'introduire des exigences inutiles.
tvCa
18
@tvCa Je trouve que les utilisateurs préfèrent généralement avoir plus de flexibilité dans leurs noms d'annuaire plutôt que d'être obligés de faciliter les choses pour les développeurs. (En fait, lorsque je traite des noms de fichiers longs, je trouve que ceux sans espaces sont pénibles car cela tue l'habillage des mots même si j'ai moi-même souffert dans le passé de ne pas tenir compte des chemins avec des espaces dans les scripts et les programmes.)
JAB
2
Ha. Les espaces ne sont que des personnages qui n'ont généralement pas de glyphes. Quoi qu'il en soit, vous pouvez leur échapper avec une barre oblique inverse.
uchuugaka
228

Notez que le test -d 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

Fichier sous: "Quand un répertoire n'est-il pas un répertoire?" La réponse: "Lorsqu'il s'agit d'un lien symbolique vers un répertoire." Un test un peu plus poussé:

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 les expressions conditionnelles Bash et la [commande intégrée et la commande [[composée .

Jon Ericson
la source
12
ou, en supposant qu'il est seulement nécessaire de travailler sur les répertoires (et les liens peuvent être ignorés) => if [ -d tmpdir -a ! -L tmpdir ]; then echo "is directory"; rmdir tmpdir; fi... ou, pour une commande qui fonctionne sur les deux liens et les répertoires:rm -r tmpdir
michael
218

Je trouve que la version à double parenthèsetest rend l'écriture des tests logiques plus naturelle:

if [[ -d "${DIRECTORY}" && ! -L "${DIRECTORY}" ]] ; then
    echo "It's a bona-fide directory"
fi
yukondude
la source
car if [[ -d "$TARFILE" ]]je reçois [[: not found
TheVillageIdiot
15
@TheVillageIdiot et @Hedgehog, utilisez-vous le shell bash? Le double support n'est pas universellement pris en charge. Voici une réponse SO sur ce point: stackoverflow.com/questions/669452/…
yukondude
6
Et dans Busybox ash avec les options de compilation par défaut [[ ]]est pris en charge, mais ne fournit en fait aucune fonctionnalité différente [ ]. Si la portabilité est un problème, respectez [ ]et utilisez les solutions de contournement nécessaires.
dubiousjim
6
... si vous utilisez des constructions bash dans un script shell, la première ligne du script doit être: #! / bin / bash (et non #! / bin / sh, ksh, etc.)
michael
Lorsque vous utilisez des crochets doubles dans bash, vous n'avez pas besoin de citer les variables.
Hubert Grzeskowiak
157

Forme plus courte:

[ -d "$DIR" ] && echo "Yes"
elmarco
la source
6
Est-ce que cela fonctionne comme ceci if $dir is a dir, then echo "yes":? Un peu d'explication aiderait :)
Martijn
5
cmd && otherest un raccourci commun pour if cmd; then other; fi- cela fonctionne avec la plupart des langages de programmation qui prennent en charge la logique booléenne, et est connu sous le nom d' évaluation de court-circuit .
tripleee
1
Le comportement n'est pas le même sous set -e(qui est une meilleure pratique de programmation shell ).
dolmen
1
@dolmen [ -d "$DIR" ]est coché (suivi de && echo Yes), donc je pense que set -ecela ne fait aucune différence dans le comportement du script (c'est-à-dire que si le test échoue, le script continue normalement).
tzot
132

Pour vérifier si un répertoire existe, vous pouvez utiliser une ifstructure 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 également le faire par la négative:

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

Remarque : soyez prudent. Laissez des espaces vides de chaque côté des accolades ouvrantes et fermantes.

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
Jorge Barroso
la source
Comment est-ce mieux que la réponse acceptée de 2008, à part aller hors sujet avec les commutateurs de fichiers?
Dan Dascalescu
mieux, à cause de [! -d répertoire / chemin vers un répertoire]
user1855805
108
  1. Un script simple pour tester si un répertoire ou un 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 si le répertoire est présent ou non

    $? si la dernière commande est réussie, elle renvoie "0", sinon une valeur non nulle. Supposons qu'il tempdirsoit déjà présent. Ensuite mkdir tempdir, donnera une erreur comme ci-dessous:

    mkdir: impossible de créer le répertoire 'tempdir': le fichier existe

yoctotutor.com
la source
4
Le second créerait le répertoire, s'il n'existait pas au début. Alors ce n'est pas idempotent.
Shihe Zhang
👆👆👆. Le 2e semble dangereux. Puisqu'il crée le répertoire, il n'est même plus vrai que le répertoire ne soit pas présent.
Chris
92

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

Remarque: La testcommande est identique à l'expression conditionnelle [(voir:) man [, elle est donc portable à travers les scripts shell.

[- Il s'agit d'un synonyme de la fonction testintégrée, mais le dernier argument doit, être un littéral ], correspondre à l'ouverture [.

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

  • help [
  • help test
  • man test ou man [
kenorb
la source
55

Ou pour quelque chose de complètement inutile:

[ -d . ] || echo "No"
qch
la source
6
Il n'imprimera jamais "Non". Le répertoire actuel existe toujours, sauf s'il est supprimé par un autre thread ou par d'autres moyens.
Jahid
Échantillon parfait :) étant donné que les réponses sont «uniques» par rapport à la réponse acceptée
Sergey Sargsyan
4
Pourquoi cela a-t-il été voté autant de fois? Cela ne répond pas à la question.
codeforester
PARCE QUE C'EST LA MEILLEURE RÉPONSE EVA
Karl Morrison
52

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
}

La bonne chose à propos de cette approche est que je n'ai pas à penser à un bon message d'erreur.

cdme donnera déjà un message standard d'une ligne à l'erreur standard . Il fournira également plus d'informations que je ne pourrai fournir. En effectuant l' cdinté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 sont juste un no-op.

Suivant 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, nous sortons à nouveau du sous-shell ( ... )et revenons de la fonction avec le message d'erreur donné.


Citant de la ksh93page de manuel:

${parameter:?word}

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

et

Si les deux points :sont omis des expressions ci-dessus, le shell vérifie uniquement si le paramètre est défini ou non.

Le phrasé ici est particulier à la documentation du shell, car il wordpeut faire référence à toute chaîne raisonnable, y compris les espaces.

Dans ce cas particulier, je sais que le message d'erreur standard 1: parameter not setn'est pas suffisant, donc je fais un zoom avant sur le type de valeur que nous attendons ici - lepathname d'un répertoire.

Une note philosophique:

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

Henk Langeveld
la source
Cela fait plus que vérifier l'existence: cette vérification de l'accessibilité au niveau de votre utilisateur. Donc, la question ne concerne que l' existence . La bonne réponse est donc test -dcomme l'a expliqué @Grundlefleck.
F.Hauri
7
@ F.Hauri - Il n'a rien demandé de plus, c'est vrai. Cependant, j'ai découvert que j'avais généralement besoin d'en savoir plus.
Henk Langeveld
Et il ne m'est jamais venu à l'esprit qu'aucun test ne peut être concluant, à moins qu'il ne s'exécute en tant que root. test -d /unreadable/existséchouera, même si l'argument existe.
Henk Langeveld
36
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.

muralikrishna
la source
1
-a est identique en effet à -e. Il est «obsolète» et son utilisation est déconseillée.
CousinCocaine
27
DIRECTORY=/tmp

if [ -d "$DIRECTORY" ]; then
    echo "Exists"
fi

Essayez en ligne

Vishal
la source
rappelez-vous spaceaprès [-> [`` -d . J'ai eu une erreur en raison d'un espace manquant
Raj
4
ENCORE , cette réponse a déjà été donnée en 2008, avec des explications plus utiles. La seule nouveauté ici est le terrain de jeu en ligne.
Dan Dascalescu
24

Tapez ce code à l'invite Bash:

if [ -d "$DIRECTORY" ]; then
    # If true this block of code will execute
fi
Santosh
la source
ENCORE , cette réponse a déjà été donnée en 2008. À quoi bon la répéter?!
Dan Dascalescu
21

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 basés sur un modèle 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
Neil Neyman
la source
Salut Niel. Votre idée peut être utile de vérifier l'existence de répertoires en fonction d'un modèle comme: find -maxdepth 1 -type d -name 'pattern'. Cela vous dérange si j'ajoute dans votre réponse cette astuce?
Santé
20

En fait, vous devez utiliser plusieurs outils pour obtenir une approche pare-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

Vous n'avez pas à vous soucier des espaces et des caractères spéciaux tant que vous utilisez "${}" .

Notez que ce [[]]n'est pas aussi portable que [], mais comme 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 important que le problème.

e-satis
la source
17

Avez-vous envisagé de faire tout ce que vous voulez faire ifplutôt que de regarder avant de sauter?

C'est-à-dire, si vous voulez vérifier l'existence d'un répertoire avant de l'entrer, essayez simplement de faire ceci:

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

Si le chemin d'accès que vous donnez pushdexiste, vous l'entrerez et il sortira avec 0, ce qui signifie que la thenpartie 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 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 les fichiers qui n'existent pas, ils vont sortir avec une erreur et imprimer un message disant qu'il n'existe pas, et votre thenbloc seront sautées. Si vous les essayez sur des fichiers qui existent, la commande s'exécutera et quittera avec un état de 0, permettant à votre thenbloc de s'exécuter.

ArtOfWarfare
la source
2
pushd est pour moi la manière la plus élégante de le faire. J'étais sur le point de le poster comme réponse :)
melMass
16
[[ -d "$DIR" && ! -L "$DIR" ]] && echo "It's a directory and not a symbolic link"

NB: La citation de variables est une bonne pratique.

Explication:

  • -d: vérifier s'il s'agit d'un répertoire
  • -L: vérifiez s'il s'agit d'un lien symbolique
Jahid
la source
Une explication serait de mise (en éditant votre réponse , pas ici dans les commentaires).
Peter Mortensen
15

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

if [ -d "$DIRECTORY1" ] && [ -d "$DIRECTORY2" ] then
    # Things to do
fi
Raamesh Keerthi
la source
comment vérifier qu'il n'existe pas?
perrohunter
15

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

[ -d "$DIRECTORY" ] || mkdir $DIRECTORY
David Okwii
la source
16
Vous pouvez utiliser mkdir -p "$DIRECTORY"pour le même effet.
Ramassage Logan du
13
[ -d ~/Desktop/TEMPORAL/ ] && echo "DIRECTORY EXISTS" || echo "DIRECTORY DOES NOT EXIST"
Juan Carlos Kuri Pinto
la source
Une explication serait de mise (en éditant votre réponse , pas ici dans les commentaires).
Peter Mortensen
11

Cette réponse enveloppée 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";
Brad Parks
la source
10

L'utilisation de la -evérification vérifie les fichiers et cela inclut les répertoires.

if [ -e ${FILE_PATH_AND_NAME} ]
then
    echo "The file or directory exists."
fi
bailey86
la source
1
Et ne répond pas correctement à la question du PO - est-ce un répertoire?
Mark Stewart
8

Selon le commentaire de Jonathan :

Si vous souhaitez créer le répertoire et qu'il n'existe pas encore, alors la technique la plus simple consiste à utiliser mkdir -pce 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 à la fois avec:

mkdir -p /some/directory/you/want/to/exist || exit 1
kenorb
la source
7
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. Vous devez peut-être également avoir des droits d'é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
Peter Mortensen
la source
7

Utilisez le fileprogramme. Étant donné que tous les répertoires sont également des fichiers sous Linux, émettre la commande suivante suffirait:

file $directory_name

Vérification d'un fichier inexistant: file blah

Production: cannot open 'blah' (No such file or directory)

Vérification d'un répertoire existant: file bluh

Production: bluh: directory

Sudip Bhandari
la source
1
Belle idée, mais dommage dans les deux cas, la commande file retourne toujours 0 code de sortie. Également lorsque le fichier / répertoire est introuvable :(.
danger89
6

La lscommande associée à l' -loption (liste longue) renvoie des informations d'attributs sur les fichiers et les répertoires.
En particulier, le premier caractère de ls -lsortie est généralement un dou un -(tiret). Dans le cas de dcelui répertorié est un répertoire à coup sûr.

La commande suivante en une seule ligne vous dira si la ISDIRvariable donnée 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
ztank1013
la source
+1, mais lorsque ISDIR n'existe pas du tout, vous obtenez un message d'erreur ainsi que votre message de diagnostic.
ysap
5
file="foo" 
if [[ -e "$file" ]]; then echo "File Exists"; fi;
ajmartin
la source
Une explication serait de mise (en éditant votre réponse , pas ici dans les commentaires).
Peter Mortensen
5

Si vous voulez vérifier si un répertoire existe, que ce soit un vrai répertoire ou 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" si le répertoire ou le lien symbolique n'existe pas, et définit également le code retour, que vous pouvez récupérer via "$?", Sur non -null (normalement "1"). Assurez-vous de vérifier le code retour directement après avoir appelé "ls".

derFunk
la source
3
Alternativement, vous pouvez utiliser cette version plus courte:if ! ls $DIR 2>/dev/null; then echo "$DIR does not exist!"; fi
derFunk
5

(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 un problème est détecté avec l'une des approches fournies ci-dessus:

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

[[ `ls -ld SAMPLE_DIR| grep ^d | wc -l` -eq 1 ]] && echo exists || not exists

-ksh: not: not found [Aucun fichier ou répertoire de ce type]

Piyush Baijal
la source
À quoi fait référence "ci-dessus"? Les trois lignes de commande de cette réponse ou des réponses précédentes? (Veuillez répondre en modifiant votre réponse , pas ici dans les commentaires. Merci d'avance.).
Peter Mortensen
4

Il existe d'excellentes solutions, mais finalement 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 indépendamment de 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 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 sur la sortie standard (pas une solution élégante à mon goût) et aura néanmoins une sortie nulle. Peut-être que quelqu'un pourrait améliorer cela.

dromichaetes
la source
13
Je serais offensé si un programme parcourait tout mon disque dur pour trouver un répertoire plutôt que de simplement chercher poliment dans mon répertoire de travail actuel ou d'utiliser le chemin absolu que je lui donne. Ce que vous avez suggéré pourrait être bien pour un outil nommé locatemais pas bien pour autre chose ...
sarnold