134 votes

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

Même lorsque /tmp n'a pas de fichier appelé something en le cherchant avec find retournera 0 :

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

Comment puis-je obtenir un statut de sortie non nul lorsque find ne trouve rien ?

2 votes

Si votre objectif est de passer la liste des noms de fichiers à une commande qui se comporte mal lorsqu'elle n'a pas d'arguments, une astuce pratique est d'ajouter simplement /dev/null comme argument supplémentaire. Il est garanti d'être vide, donc si votre but est d'exécuter wc c'est particulièrement utile. Ce n'est pas une réponse à tous les cas d'utilisation.

108voto

Priyan R Points 687
find /tmp -name something | grep .

L'état de retour sera 0 lorsque quelque chose est trouvé, et non-zéro sinon.

EDIT : Changé de egrep '.*' à celle, beaucoup plus simple, de grep . puisque le résultat est le même.

15 votes

La queue * sur le egrep regex est complètement redondant. Puisque vous n'utilisez pas egrep syntaxe d'expression régulière, simple grep pourrait être plus rapide de quelques microsecondes.

6 votes

J'ai appris à utiliser find ... | read

0 votes

Read renvoie le code de sortie approprié, mais notez qu'il avale le résultat s'il y en a un.

40voto

Zombo Points 1119

La sortie 0 est facile à trouver, la sortie >0 est plus difficile parce que cela n'arrive généralement que qu'en cas d'erreur. Cependant, nous pouvons faire en sorte que cela se produise :

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

8 votes

Pour autant que je sache, cela ne fonctionne pas. Le code de sortie de find ne semble pas dépendre des codes de sortie d'une quelconque -exec s qu'il a couru.

4 votes

Fonctionne comme une horloge. L'un des grands avantages de cette solution est qu'elle n'utilise pas de tuyaux de sous-shells, ce qui est intéressant pour certains besoins de script.

1 votes

Non, cela ne fonctionnera pas comme la question a été posée. Cette solution renverra 1 si le fichier est trouvé. Elle renverra 0 si le fichier est trouvé. C'est le contraire de ce que le PO a demandé. Cependant, cette solution fonctionne en tant que concept, mais elle ne répond pas à la question.

28voto

Matt Kneiser Points 379

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

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

6 votes

Les guillemets ne servent à rien ici.

7 votes

Bien que les guillemets doubles n'aient aucune fonction de code, ils indiquent plus clairement au lecteur que le caractère point est une regex et non un répertoire.

2 votes

Et si vous voulez l'inverse (sortie non nulle lorsque le fichier est trouvé), vous pouvez ajouter un opérateur de négation en amont ! find /tmp -name badfile | grep -q .

17voto

shearn89 Points 3102

Je viens de trouver cette question en essayant de trouver ma façon de résoudre un problème avec Puppet (changer les permissions sur les dossiers sous un répertoire mais pas sur le répertoire lui-même), ceci semble fonctionner :

test -n "$(find /tmp -name something)"

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

test -n "$(find /home -mindepth 1 -maxdepth 1 -perm -711)"

Ce qui donnera le code de sortie 1 si la commande find ne trouve aucun fichier avec les permissions requises.

0 votes

Quelques solutions (je ne les ai pas toutes essayées) ne fonctionnaient pas sur un Mac ; celle-ci a fonctionné.

1 votes

Pour mémoire, cela peut aussi s'écrire comme suit [[ -n "$(...)" ]] si les gens trouvent cela plus lisible que d'utiliser test .

0 votes

J'aime cette solution car elle permet d'éviter le pipe et le bumping du compteur PID. [ "$(find ...)" ] && echo Found || echo Not found avec un seul support et sans -n fonctionne également et est portable (POSIX).

7voto

Sven Points 95985

Ce n'est pas possible. Find renvoie 0 s'il se termine avec succès, même s'il n'a pas trouvé de fichier (ce qui est un résultat correct). no indiquant une erreur lorsque le fichier n'existe pas).

Pour citer la page de manuel de find

STATUT DE SORTIE

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

En fonction de ce que vous voulez obtenir, vous pouvez essayer de laisser trouver -print le nom du fichier et de tester contre sa sortie :

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

1 votes

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

0 votes

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

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X