Kann ich `find` dazu bringen, dass es nicht 0 ist, wenn keine passenden Dateien gefunden werden?

46

Selbst wenn /tmpkeine Datei aufgerufen wurde something, gibt die Suche mit find0 zurück:

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

Wie kann ich einen Exit-Status ungleich Null erhalten, wenn findnichts gefunden wird?

yael
quelle

Antworten:

44

Hier ist ein Einzeiler, von dem ich glaube, dass er macht, was Sie wollen:

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

Der Rückgabestatus ist, 0wenn etwas gefunden wurde, andernfalls nicht Null.

Wenn Sie auch die Ausgabe von findfür die weitere Verarbeitung erfassen müssen , hat die Antwort von Sven dies abgedeckt.

Steven Montag
quelle
14
Das Schleppen *auf dem egrepRegex ist vollständig überflüssig. Da Sie keine egrepSyntax für reguläre Ausdrücke verwenden, ist plain old grepmöglicherweise einige Mikrosekunden schneller.
Tripleee
Ich lernte zu verwendenfind ... | read
Sam
14

Einfachste Lösung, die nicht druckt, aber 0 verlässt, wenn Ergebnisse gefunden werden

find /tmp -name something | grep -q "."
Matt Kneiser
quelle
2
Doppelte Anführungszeichen haben hier keinen Zweck.
haridsv
Die doppelten Anführungszeichen haben zwar keine Codefunktion, machen dem Leser jedoch klarer, dass das Punktzeichen ein regulärer Ausdruck und kein Verzeichnis ist.
Dharma Bellamkonda
13

Exit 0 ist mit find einfach, Exit> 0 ist schwieriger, weil das normalerweise nur mit einem Fehler passiert. Wie auch immer, wir können es schaffen:

if find -type f -exec false {} +
then
  echo 'nothing found'
else
  echo 'something found'
fi
Steven Penny
quelle
2
Soweit ich das beurteilen kann, funktioniert das nicht. Der Exit-Code von findscheint nicht von den Exit-Codes der von ihm ausgeführten -execs abzuhängen .
Chris
@ Chris arbeitet für mich, und die 4, die aufgestimmt
Steven Penny
Beispiel für ein falsches Ergebnis dieser Lösung: find / existierender-Startpunkt / nicht existierender-Startpunktname file-in-existierender-Startpunkt -exec false {} +
Gerald Schade
2
Dies funktioniert ordnungsgemäß und ist dokumentiert (obwohl im execAbschnitt ausgeblendet , nicht unter Rückgabewert). Es kann nicht zwischen nichts, was gefunden wurde, und sich selbst als fehlerhaft herausstellen (z. B. wenn es an einem nicht existierenden Ausgangspunkt aufgerufen wurde).
Tgr
Wenn Sie diese Funktionalität benötigen - ja
Gerald Schade
7

Nachdem ich diese Frage gerade gefunden habe, als ich versucht habe, ein Problem mit Puppet zu lösen (Berechtigungen für Ordner in einem Verzeichnis ändern, aber nicht für das Verzeichnis selbst), scheint dies zu funktionieren:

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

Mein spezieller Anwendungsfall ist dieser:

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

Womit Code 1 beendet wird, wenn der Befehl find keine Dateien mit den erforderlichen Berechtigungen findet.

shearn89
quelle
Ein paar Lösungen (haben nicht alle ausprobiert) funktionierten hier nicht auf einem Mac. das tat.
Alex Hall
5

Es ist nicht möglich. Find gibt 0 zurück, wenn es erfolgreich beendet wurde, auch wenn es keine Datei gefunden hat (was ein korrektes Ergebnis ist und keinen Fehler anzeigt, wenn die Datei tatsächlich nicht existiert).

Zitiert die Suchmanpage

EXIT STATUS

find-Exits mit Status 0, wenn alle Dateien erfolgreich verarbeitet wurden, größer als 0, wenn Fehler auftreten. Dies ist absichtlich eine sehr breite Beschreibung. Wenn der Rückgabewert jedoch nicht Null ist, sollten Sie sich nicht auf die Richtigkeit der Ergebnisse von find verlassen.

Je nachdem, was Sie erreichen möchten, können Sie versuchen, -printden Dateinamen zu ermitteln und anhand der Ausgabe zu testen:

#!/bin/bash
MYVAR=`find . -name "something" -print`
if [ -z "$MYVAR" ]; then
    echo "Notfound"
else
   echo $MYVAR
fi
Sven
quelle
Es ist sicherlich möglich , auch wenn es nicht so robust ist, wie man es sich wünscht.
Ruslan
Die Handbuchseite ist schlecht organisiert. Was Ruslan sagte, ist unter der Option exec/ dokumentiert execdir(verwendet mit +):If any invocation returns a non-zero value as exit status, then find returns a non-zero exit status.
Tgr
1

Ich halte dies für die prägnanteste und direkteste Methode:

test `find /tmp/ -name something -print -quit 2>/dev/null`
Danorton
quelle
2
In diesem Fall würde find, wenn ein Fehler aufgetreten wäre, das Ergebnis nach / dev / null ausgeben, einen Exit ungleich Null zurückgeben und diesen dann durch den Testbefehl auf 0 setzen.
Jeff Ferland
Ich glaube nicht, dass das stimmt. Bitte beschreiben Sie Ihr Beispiel. Wenn ein Fehler auftritt und Exits gefunden werden, ist die Zeichenfolge leer und test gibt einen Wert ungleich Null zurück.
Danorton
Ich bin mir nicht sicher, was Ihr Beispiel sein könnte, aber ich habe es versehentlich weggelassen -print -quit, was Ihr Anliegen ansprechen könnte.
Danorton
Vielleicht kann die andere Person, die (vermutlich aus demselben Grund) abstimmte, ein gegenteiliges Beispiel liefern?
Danorton
1
Okay, du magst meinen Stil einfach nicht. In meinen Anwendungsfällen sind alle gefundenen Fehler entweder Rauschen oder so schwerwiegend, dass sie an anderer Stelle angezeigt werden. In jedem Fall beantwortet diese Methode die letzte Frage richtig: "Gibt es eine zugreifbare Datei im Pfad mit dem angegebenen Namen." Ein Fehler gibt die korrekte Antwort "Nein" zurück. Wenn ich herausfinden möchte, warum nicht, kann ich komplexeren Code hinzufügen, der Fragen beantwortet, die ursprünglich hier nicht gestellt wurden.
Danorton
0

Hier ist ein kleines Skript, das ich angerufen habe test.py. Es verbessert andere Methoden dahingehend, dass es einen Fehlercode zurückgibt, wenn einer festgelegt ist, und zusätzlich einen, wenn find keine Dateien auflistet:

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)

Hier ist die Befehlszeilenausgabe:

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

Für ein Ergebnis, bei dem find Fehler hatte, aber Dateien gefunden hat:

$ 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

Dann, wenn Sie die Liste der Dateien möchten , können Sie Gebrauch machen -print 0weitergegeben findund spalten das aus Variable auf NULL - Werten, oder Sie können nur eine print - Anweisung für hinzufügen.

Jeff Ferland
quelle
-1

Es ist nicht nur so, finddass die Exit-Statuscodes bei Erfolg als Null zurückgegeben werden. In Unix gibt der Befehl, den Sie ausführen, bei Erfolg den Exit-Status als Null zurück.

Informatica-Oracle-Unix
quelle