Je veux tester si un répertoire ne contient aucun fichier. Si tel est le cas, je vais ignorer certains traitements.
J'ai essayé ce qui suit:
if [ ./* == "./*" ]; then
echo "No new file"
exit 1
fi
Cela donne l'erreur suivante:
line 1: [: too many arguments
Y a-t-il une solution / alternative?
Réponses:
En outre, il serait intéressant de vérifier si le répertoire existe avant.
la source
&&
et||
simultanément! Siecho "Not Empty"
échoue,echo "Empty"
va courir! Essayezecho "test" && false || echo "fail"
! Oui, je sais queecho
cela ne va pas échouer, mais si vous modifiez une autre commande, vous serez surpris![ "$(ls -A /)" ] && touch /non-empty || echo "Empty"
- Si vous voulez "marquer" les répertoires non vides avec un fichier créé nomménon-empty
, échouera et affichera "Vide".touch /empty
ma ligne?if [ -n "$(ls -A /path/to/dir)" ]; then
... Merci de mettre à jour la réponse avant que quelqu'un ne colle ce code quelque part sur son serveur et qu'un pirate informatique détermine comment l'exploiter. Si ce/path/to/dir
n'est pas vide, alors les noms de fichiers y sont passés en tant qu'arguments/bin/test
auxquels il n'est clairement pas destiné. Il suffit d'ajouter l'-n
argument, problème résolu. Merci!Pas besoin de compter quoi que ce soit ou des globes de shell. Vous pouvez également utiliser
read
en combinaison avecfind
. Sifind
la sortie est vide, vous retournerezfalse
:Cela devrait être portable.
la source
echo
appels reflètent un résultat erroné: lors de mon test (sous Cygwin),find . -mindepth 1 | read
un code d'erreur 141 était indiqué dans un répertoire non vide et 0 dans un répertoire videread
retourne 0, et pour un vide, 1.set -o pipefail
la source
-n
soit correct et sûr (test avec un répertoire avec des espaces dans le nom, testez-le avec un répertoire non vide avec le nom '0 = 1').... [ -n "$(find "$DIR_TO_CHECK" -maxdepth 0 -type d -empty 2>/dev/null)" ]; ...
grep
. serverfault.com/questions/225798/…find "$DIR_TO_CHECK" -maxdepth 0 -type d -empty | grep .
et de s'appuyer sur l'état de sortie de grep. Quelle que soit la façon dont vous le faites, c'est vraiment la bonne réponse à cette question.la source
Cela fera le travail dans le répertoire de travail courant (.):
ou la même commande divisée sur trois lignes juste pour être plus lisible:
Il suffit de remplacer
ls -1A . | wc -l
parls -1A <target-directory> | wc -l
si vous devez l'exécuter sur un autre dossier cible.Edit : j'ai remplacé
-1a
par-1A
(voir commentaire @Daniel)la source
ls -A
place. Certains systèmes de fichiers n'ont pas.
et les..
liens symboliques selon les docs.-1
est définitivement redondant. Même sils
vous n'imprimerez pas un élément par ligne au moment où il sera importé, cela n'affectera pas l'idée de vérifier si elle produit zéro ligne ou plus.Utilisez le suivant:
De cette façon, vous êtes indépendant du format de sortie de
ls
.-mindepth
ignore le répertoire lui-même,-maxdepth
empêche la défense récursive dans des sous-répertoires pour accélérer les choses.la source
wc -l
et lefind
format de sortie (qui est raisonnablement clair que).Utiliser un tableau:
la source
shopt -s nullglob
${#files[@]} == 2
hypothèse ne correspond pas au répertoire racine (vous ne testerez probablement pas s'il est vide, mais il est possible que du code ne sachant pas cette limitation).Un hacky, mais uniquement bash, sans PID:
Ceci tire parti du fait que les commandes
test
internes construites avec 2 si plus d'un argument est donné après-e
: Tout d'abord,"$1"/*
glob est développé par bash. Cela se traduit par un argument par fichier. AlorsS'il n'y a pas de fichiers, l'astérisque
test -e "$1"*
ne se développe pas, donc Shell retourne à l'essai du fichier nommé*
, qui renvoie 1.... sauf s'il y a un fichier nommé exactement
*
, alors l'astérisque se développe pour bien, astérisque, qui se termine comme le même appel que ci-dessus, c'est-à-dire.test -e "dir/*"
, cette fois, retourne 0. (Merci @TrueY pour l'avoir signalé.)S'il y a un fichier,
test -e "dir/file"
est exécuté, ce qui retourne 0.Mais s'il y a plus de fichiers que 1,
test -e "dir/file1" "dir/file2"
est exécuté, ce qui est signalé par bash comme une erreur d'utilisation, c'est-à-dire 2.case
englobe toute la logique de sorte que seul le premier cas, avec 1 état de sortie, soit signalé comme ayant abouti.Problèmes possibles que je n'ai pas vérifiés:
Il y a plus de fichiers que le nombre d'arguments autorisés - je suppose que cela pourrait se comporter de la même manière que le cas de 2 fichiers ou plus.
Ou alors il y a un fichier avec un nom vide - je ne suis pas sûr que ce soit possible avec n'importe quel système d'exploitation / système d'exploitation.
la source
test -e dir/*
est appelé. Si le seul fichier est '*' dans le répertoire, le test retournera 0. S'il y a plus de fichiers, il en retournera 2. Donc, cela fonctionne comme décrit.Avec FIND (1) (sous Linux et FreeBSD), vous pouvez regarder de manière non récursive une entrée de répertoire via "-maxdepth 0" et tester si elle est vide avec "-empty". Appliqué à la question cela donne:
la source
Je pense que la meilleure solution est:
grâce à https://stackoverflow.com/a/91558/520567
Ceci est une édition anonyme de ma réponse qui pourrait être utile ou non à quelqu'un: Une légère modification indique le nombre de fichiers:
Cela fonctionnera correctement même si les noms de fichiers contiennent des espaces.
la source
EDIT: Je pense que cette solution fonctionne bien avec gnu find, après un rapide aperçu de la mise en œuvre . Mais cela peut ne pas fonctionner avec, par exemple, la recherche de netbsd . En effet, celui-ci utilise le champ st_size de stat (2). Le manuel le décrit comme:
Une meilleure solution, également plus simple, est:
De plus, la solution -une dans la 1ère solution est inutile.
EDIT: no -exit for gnu find .. la solution ci-dessus est bonne pour la recherche de NetBSD. Pour GNU find, cela devrait fonctionner:
la source
-exit
prédicat .Ce sont toutes d'excellentes choses - il suffit d'en faire un script pour que je puisse rechercher des répertoires vides sous le répertoire actuel. Le fichier ci-dessous devrait être placé dans un fichier nommé 'findempty', placé quelque part dans le chemin afin que bash puisse le trouver, puis exécuter chmod 755. Peut facilement être adapté à vos besoins spécifiques, je suppose.
la source
Ce travail pour moi, pour vérifier et traiter les fichiers dans le répertoire
../IN
, considérant que le script est dans le../Script
répertoire:la source
Qu'en est-il de tester si le répertoire existe et non vide dans une instruction if
la source
Pour tout répertoire autre que celui en cours, vous pouvez vérifier s'il est vide en le tentant
rmdir
, car ilrmdir
est garanti que les répertoires non vides échouent. Si celarmdir
réussit et que vous vouliez réellement que le répertoire vide survive au test,mkdir
recommencez.N'utilisez pas ce hack s'il y a d'autres processus qui pourraient être perturbés par un répertoire dont ils savent qu'ils cessent brièvement d'exister.
Si
rmdir
cela ne fonctionne pas pour vous et que vous testez peut-être des répertoires pouvant contenir un grand nombre de fichiers, toute solution reposant sur l'écorchage du shell peut être lente et / ou respecter les limites de longueur de ligne de commande. Probablement préférable d'utiliserfind
dans ce cas. Lafind
solution la plus rapide à laquelle je peux penser va commeCela fonctionne pour les versions GNU et BSD de
find
Solaris, mais pas pour celle de Solaris, qui manque à chacun de cesfind
opérateurs. Aimez votre travail, Oracle.la source
Vous pouvez essayer de supprimer le répertoire et attendre une erreur. rmdir ne supprimera pas le répertoire s'il n'est pas vide.
la source
rmdir
échouera si je n'ai pas la permission de supprimer le répertoire; ou s'il s'agit d'un sous-volume Btrfs; ou s'il appartient à un système de fichiers en lecture seule. Et sirmdir
n'échoue pas etmkdir
fonctionne: que se passe-t-il si le répertoire déjà supprimé appartient à un autre utilisateur? Qu'en est-il de ses autorisations (éventuellement non standard)? ACL? attributs étendus? Tout perdu.