Quelle commande peut être utilisée pour vérifier si un répertoire existe ou non, dans un script shell Bash?
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.
--
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.[ ! -d "$DIRECTORY" ]
sera vraie soit si elle$DIRECTORY
n'existe pas, soit si elle existe mais n'est pas un répertoire. Considérez quelque chose commeif [ ! -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 amkdir
réussi de toute façon; il y a un certain nombre de raisons pour lesquelles cela peut échouer.)-d
) et le lien symbolique (-L
), il est plus facile d'ajouter simplement une barre oblique à la variable, commeif [ -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.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
$DIRECTORY
set to"My M0viez"
et votre script explosera. Tu ne veux pas ça. Alors utilisez ça.la source
Notez que le test -d peut produire des résultats surprenants:
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é:
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 .la source
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
Je trouve que la version à double parenthèse
test
rend l'écriture des tests logiques plus naturelle:la source
if [[ -d "$TARFILE" ]]
je reçois [[: not found[[ ]]
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.Forme plus courte:
la source
if $dir is a dir, then echo "yes"
:? Un peu d'explication aiderait :)cmd && other
est un raccourci commun pourif 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 .set -e
(qui est une meilleure pratique de programmation shell ).[ -d "$DIR" ]
est coché (suivi de&& echo Yes
), donc je pense queset -e
cela ne fait aucune différence dans le comportement du script (c'est-à-dire que si le test échoue, le script continue normalement).Pour vérifier si un répertoire existe, vous pouvez utiliser une
if
structure simple comme celle-ci:Vous pouvez également le faire par la négative:
Remarque : soyez prudent. Laissez des espaces vides de chaque côté des accolades ouvrantes et fermantes.
Avec la même syntaxe, vous pouvez utiliser:
la source
Un script simple pour tester si un répertoire ou un fichier est présent ou non:
Un script simple pour vérifier si le répertoire est présent ou non:
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'iltempdir
soit déjà présent. Ensuitemkdir tempdir
, donnera une erreur comme ci-dessous:la source
Vous pouvez utiliser
test -d
(voirman test
).Par exemple:
Remarque: La
test
commande est identique à l'expression conditionnelle[
(voir:)man [
, elle est donc portable à travers les scripts shell.Pour les options possibles ou une aide supplémentaire, consultez:
help [
help test
man test
ouman [
la source
Ou pour quelque chose de complètement inutile:
la source
Voici un idiome très pragmatique:
Je l'enveloppe généralement dans une fonction:
Ou:
La bonne chose à propos de cette approche est que je n'ai pas à penser à un bon message d'erreur.
cd
me 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'cd
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 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
ksh93
page de manuel:et
Le phrasé ici est particulier à la documentation du shell, car il
word
peut 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 set
n'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
pathname
nondirectory
. À ce niveau, je préfère rester simple - les arguments d'une fonction ne sont que des chaînes.la source
test -d
comme l'a expliqué @Grundlefleck.test -d /unreadable/exists
échouera, même si l'argument existe.Le code ci-dessus vérifie si le répertoire existe et s'il est accessible en écriture.
la source
Essayez en ligne
la source
space
après[
-> [`` -d . J'ai eu une erreur en raison d'un espace manquantTapez ce code à l'invite Bash:
la source
Plus de fonctionnalités en utilisant
find
Vérifiez l'existence du dossier dans les sous-répertoires:
Vérifiez l'existence d'un ou plusieurs dossiers basés sur un modèle dans le répertoire courant:
Les deux combinaisons. Dans l'exemple suivant, il vérifie l'existence du dossier dans le répertoire courant:
la source
find -maxdepth 1 -type d -name 'pattern'
. Cela vous dérange si j'ajoute dans votre réponse cette astuce?En fait, vous devez utiliser plusieurs outils pour obtenir une approche pare-balles:
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.la source
Avez-vous envisagé de faire tout ce que vous voulez faire
if
plutô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:
Si le chemin d'accès que vous donnez
pushd
existe, vous l'entrerez et il sortira avec0
, ce qui signifie que lathen
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 un effet secondaire utile pour le débogage).Cela semble mieux que cela, ce qui nécessite de se répéter:
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 votrethen
bloc seront sautées. Si vous les essayez sur des fichiers qui existent, la commande s'exécutera et quittera avec un état de0
, permettant à votrethen
bloc de s'exécuter.la source
Explication:
-d
: vérifier s'il s'agit d'un répertoire-L
: vérifiez s'il s'agit d'un lien symboliquela source
Pour vérifier plusieurs répertoires, utilisez ce code:
la source
Vérifiez si le répertoire existe, sinon faites-en un:
la source
mkdir -p "$DIRECTORY"
pour le même effet.la source
Cette réponse enveloppée comme un script shell
Exemples
is_dir
la source
L'utilisation de la
-e
vérification vérifie les fichiers et cela inclut les répertoires.la source
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 -p
ce 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:la source
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:
la source
Utilisez le
file
programme. É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
la source
La
ls
commande associée à l'-l
option (liste longue) renvoie des informations d'attributs sur les fichiers et les répertoires.En particulier, le premier caractère de
ls -l
sortie est généralement und
ou un-
(tiret). Dans le cas ded
celui répertorié est un répertoire à coup sûr.La commande suivante en une seule ligne vous dira si la
ISDIR
variable donnée contient ou non un chemin vers un répertoire:Utilisation pratique:
la source
la source
Si vous voulez vérifier si un répertoire existe, que ce soit un vrai répertoire ou un lien symbolique, utilisez ceci:
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".
la source
if ! ls $DIR 2>/dev/null; then echo "$DIR does not exist!"; fi
(1)
(2)
(3)
Si un problème est détecté avec l'une des approches fournies ci-dessus:
Avec la
ls
commande; les cas où un répertoire n'existe pas - un message d'erreur s'affichela source
Il existe d'excellentes solutions, mais finalement chaque script échouera si vous n'êtes pas dans le bon répertoire. Donc, codez comme ceci:
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:
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.
la source
locate
mais pas bien pour autre chose ...