Puis-je faire en sorte que `find` renvoie non-0 quand aucun fichier correspondant n'est trouvé?


46

Même quand /tmpaucun fichier n'a été appelé something, la recherche avec findretournera 0:

  $ find /tmp -name something 
  $ echo $?
  0

Comment puis-je obtenir un statut de sortie non nul quand findne trouve rien?

Réponses:


44

Voici une ligne qui, je crois, fait ce que vous voulez:

find /tmp -name something | egrep '.*'

L'état de retour sera 0quand quelque chose est trouvé et différent de zéro sinon.

Si vous devez également capturer la sortie de findpour un traitement ultérieur, alors la réponse de Sven a couvert cela.


14
La fin *sur la egrepregex est complètement redondante. Puisque vous n'utilisez pas egrepla syntaxe d'expression régulière, cela greppeut prendre quelques microsecondes plus rapidement.
triple-

J'ai appris à utiliserfind ... | read
Sam

14

La solution la plus simple qui n'imprime pas, mais quitte 0 lorsque les résultats sont trouvés

find /tmp -name something | grep -q "."

2
Les guillemets ne servent à rien ici.
haridsv

Bien que les guillemets doubles ne servent à aucune fonction de code, ils indiquent clairement au lecteur que le caractère point est une regex et non un répertoire.
Dharma Bellamkonda

13

La sortie 0 est facile avec find, exit> 0 est plus difficile car cela ne se produit généralement qu'avec une erreur. Cependant, nous pouvons y arriver:

if find -type f -exec false {} +
then
  echo 'nothing found'
else
  echo 'something found'
fi

2
Autant que je sache, cela ne fonctionne pas. Le code de sortie de findne semble pas dépendre des codes de sortie des programmes -execqu’il a exécutés.
Chris

@Chris travaille pour moi et les 4 qui ont voté
Steven Penny

exemple pour résultat faussement faux de cette solution: recherche / point de départ existant / point de départ non existant nom de fichier dans le point de départ existant -exec false {} +
Gerald Schade

2
Cela fonctionne correctement et est documenté (bien que caché dans la execsection, pas sous la valeur de retour). Il ne peut pas différencier rien trouvé et se trouver en erreur (par exemple, quand il a été invoqué sur un point de départ inexistant).
Tgr

Si vous avez besoin de cette fonctionnalité - oui
Gerald Schade

7

Ayant trouvé cette question tout en essayant de trouver un moyen de résoudre un problème avec Puppet (modifier les autorisations sur les dossiers situés dans un répertoire mais pas sur le répertoire lui-même), cela semble fonctionner:

! test -z $(find /tmp -name something)

Mon cas d'utilisation spécifique est le suivant:

! test -z $(find /home -mindepth 1 -maxdepth 1 -perm -711)

Ce qui quittera le code 1 si la commande find ne trouve aucun fichier avec les autorisations requises.


Quelques solutions (ne les ont pas toutes essayées) ici ne fonctionnaient pas sur un Mac; cela a fait.
Alex Hall le

5

Ce n'est pas possible. Find renvoie 0 s'il réussit, même s'il n'a pas trouvé de fichier (résultat correct n'indiquant pas d'erreur lorsque le fichier n'existe pas).

Pour citer la page de manuel de recherche

STATUS DE SORTIE

trouver les exits avec le statut 0 si tous les fichiers sont traités avec succès, supérieur à 0 si des erreurs se produisent. C'est délibérément une description très large, mais si la valeur de retour est différente de zéro, vous ne devez pas vous fier à l'exactitude des résultats de find.

Selon ce que vous souhaitez réaliser, vous pouvez essayer de trouver -printle nom du fichier et de le tester par rapport à sa sortie:

#!/bin/bash
MYVAR=`find . -name "something" -print`
if [ -z "$MYVAR" ]; then
    echo "Notfound"
else
   echo $MYVAR
fi

C'est certainement possible , mais pas aussi robuste qu'on pourrait le souhaiter.
Ruslan

La page de manuel est mal organisée; ce que Ruslan a dit est documenté sous l’ option exec/ execdir(utilisé avec +):If any invocation returns a non-zero value as exit status, then find returns a non-zero exit status.
Tgr

1

Je pense que c'est la méthode la plus concise et la plus directe:

test `find /tmp/ -name something -print -quit 2>/dev/null`

2
Dans ce cas, si find avait une erreur, il imprimait le résultat dans / dev / null, renvoyait une sortie non nulle et fixait ensuite le résultat à 0 avec la commande test.
Jeff Ferland

Je ne crois pas que ce soit vrai. S'il vous plaît décrire votre exemple. S'il y a une erreur et que vous trouvez des exits, la chaîne sera vide et test renverra une valeur autre que zéro.
danorton

Je ne suis pas sûr de ce que votre exemple pourrait être, mais j'ai accidentellement omis -print -quit, ce qui pourrait répondre à votre préoccupation.
danorton

Peut-être que l’autre personne qui a rétrogradé (probablement pour la même raison) peut donner un exemple contraire?
danorton

1
Ok, tu n'aimes pas mon style. Dans mes cas d'utilisation, les erreurs détectées sont soit du bruit, soit si graves qu'elles seront affichées ailleurs. Dans tous les cas, cette méthode répond correctement à la dernière question: "Y a-t-il un fichier accessible dans le chemin par le nom donné". Une erreur retournera une réponse correcte de "Non". Si je veux savoir pourquoi, je peux ajouter un code plus complexe qui répond aux questions non posées à l'origine.
danorton

0

Voici un petit script que j'ai appelé test.py. Il améliore les autres méthodes publiées en ce sens qu'il renvoie un code d'erreur s'il est défini, et en ajoute un si find ne répertorie aucun fichier:

from subprocess import Popen
import sys

p = Popen(['find'] + sys.argv)
out, err = p.communicate()
if p.returncode:
    sys.exit(p.returncode)
if not out:
    sys.exit(1)

Voici la sortie en ligne de commande:

$ python test.py . -maxdepth 1 -name notthere
$ echo $?
1
$ find . -maxdepth 1 -name notthere
$ echo $?
0
$ find . -failedarg
find: unknown predicate `-failedarg'
$ echo $?
1

Ensuite, pour un résultat où find avait des erreurs mais des fichiers trouvés:

$ ls -lh
$ d---------  2 jeff users   6 Feb  6 11:49 noentry
$ find .
.
./noentry
find: `./noentry': Permission denied
$ echo $?
1
$ find . | egrep '.*'
.
./noentry
find: `./noentry': Permission denied
$ echo $?
0
python ../test.py 
../test.py
$ echo $?
1

Ensuite, si vous voulez la liste de fichiers que vous pouvez utiliser, -print 0transmettez findet divisez la variable out sur les valeurs null, ou vous pouvez simplement ajouter une instruction print pour elle.


-1

Ce n'est pas seulement findque renvoie les codes d'état de sortie à zéro lorsqu'il réussit. Sous Unix quelle que soit la commande que vous exécutez, si elle réussit, elle renvoie l'état de sortie à zéro.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.