Vérifier si un répertoire existe dans un script shell
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.
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
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 .
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
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
if [ -d "$DIRECTORY" ]; then
# Here if $DIRECTORY exists
fi
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 detest
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
ouman [
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'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, Imprimezword
et sortez du shell (si non interactif). Siword
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.
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.
-
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
-
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 quetempdir
soit déjà présent alorsmkdir tempdir
sera donnez l'erreur comme ci-dessous:mkdir: ne peut créer le répertoire ‘rep’: le Fichier existe déjà
tapez ce code sur le bash promt
if [ -d "$DIRECTORY" ]; then
# if true this block of code will execute
fi
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
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é.
pour vérifier plus d'un répertoire, 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 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.
[[ -d "$DIR" && ! -L "$DIR" ]] && echo "It's a directory and not a symbolic link"
N. B: citer des variables est une bonne pratique.
vérifiez si le répertoire existe, sinon faites-en un
[ -d "$DIRECTORY" ] || mkdir $DIRECTORY
[ -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 [ "" == "help" ]
then
show_help
fi
if [ -z "" ]
then
show_help
fi
DIR=
if [ -d $DIR ]; then
echo "YES";
exit;
fi
echo "NO";
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
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
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
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
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".
(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]
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.
ci-dessous find peut être utilisé,
find . -type d -name dirname -prune -print