Posso fare in modo che `find` restituisca un valore diverso da 0 quando non viene trovato alcun file corrispondente?


46

Anche quando /tmpnon è stato chiamato alcun file something, cercandolo con findverrà restituito 0:

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

Come posso ottenere uno stato di uscita diverso da zero quando findnon trova nulla?

Risposte:


44

Ecco un one-liner che credo faccia quello che vuoi:

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

Lo stato di ritorno sarà 0quando viene trovato qualcosa, e diverso da zero altrimenti.

Se è necessario acquisire anche l'output di findper ulteriori elaborazioni, la risposta di Sven lo ha coperto.


14
Il finale *sul egrepregex è completamente ridondante. Dal momento che non stai usando egrepla sintassi delle espressioni regolari, la vecchia greppotrebbe essere più veloce di alcuni microsecondi.
Tripleee

ho imparato a usarefind ... | read
Sam,

14

Soluzione più semplice che non stampa, ma esce 0 quando vengono trovati i risultati

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

2
Le doppie virgolette non servono a nulla qui.
haridsv,

Mentre le doppie virgolette non hanno alcuna funzione di codice, rendono più chiaro a un lettore che il carattere punto è una regex e non una directory.
Dharma Bellamkonda,

13

Exit 0 è facile con find, exit> 0 è più difficile perché ciò accade di solito solo con un errore. Tuttavia possiamo farlo accadere:

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

2
Per quanto ne so, questo non funziona. Il codice di uscita di findnon sembra dipendere dai codici di uscita di tutti -execi messaggi in esecuzione.
Chris,

@Chris lavora per me e per i 4 che hanno votato
Steven Penny il

esempio di risultato erroneamente falso di questa soluzione: find / esistenti-punto di partenza / non-esistente-punto-di-inizio file-in-esistente-punto di partenza -esatto falso {} +
Gerald Schade

2
Funziona correttamente ed è documentato (sebbene nascosto nella execsezione, non sotto il valore restituito). Non può distinguere tra nulla trovato e trovarsi ad errori (ad es. Quando è stato invocato su un punto di partenza inesistente).
Tgr

Se hai bisogno di questa funzionalità - sì
Gerald Schade il

7

Avendo appena trovato questa domanda mentre cercavo di trovare il mio modo di risolvere un problema con Puppet (cambia i permessi sulle cartelle in una directory ma non sulla directory stessa), questo sembra funzionare:

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

Il mio caso d'uso specifico è questo:

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

Che uscirà dal codice 1 se il comando find non trova file con le autorizzazioni richieste.


Alcune soluzioni (non le ho provate tutte) qui non hanno funzionato su un Mac; questo ha fatto.
Alex Hall,

5

Non è possibile. Trova restituisce 0 se esce correttamente, anche se non ha trovato un file (che è un risultato corretto che non indica un errore quando il file effettivamente non esiste).

Per citare la manpage di ricerca

STATO DI USCITA

trova le uscite con stato 0 se tutti i file vengono elaborati correttamente, maggiore di 0 se si verificano errori. Questa è deliberatamente una descrizione molto ampia, ma se il valore restituito è diverso da zero, non si dovrebbe fare affidamento sulla correttezza dei risultati di find.

A seconda di ciò che si desidera ottenere, è possibile provare a trovare -printil nome del file e verificarne l'output:

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

È certamente possibile , anche se non così robusto come si potrebbe desiderare.
Ruslan,

La pagina del manuale è mal organizzata; ciò che ha detto Ruslan è documentato sotto l' opzione exec/ execdir(usato con +):If any invocation returns a non-zero value as exit status, then find returns a non-zero exit status.
Tgr

1

Sento che questo è il metodo più conciso e diretto:

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

2
In questo caso, se find ha avuto un errore, stampa il risultato su / dev / null, restituisce un'uscita diversa da zero e quindi viene fissato a 0 dal comando test.
Jeff Ferland,

Non credo sia vero. Descrivi il tuo esempio. Se si verifica un errore e trova le uscite, la stringa sarà vuota e il test restituirà un valore diverso da zero.
Danorton,

Non sono sicuro di quale potrebbe essere il tuo esempio, ma ho accidentalmente omesso -print -quit, il che potrebbe rispondere alla tua preoccupazione.
Danorton,

Forse l'altra persona che ha effettuato il downgrade (presumibilmente per lo stesso motivo) può fornire un esempio contrario?
danorton,

1
Okay, non ti piace il mio stile. Per i miei casi d'uso, eventuali errori rilevati potrebbero essere rumorosi o così gravi da essere visualizzati altrove. In ogni caso, questo metodo risponde correttamente alla domanda finale: "Esiste un file accessibile nel percorso con il nome dato". Un errore restituirà una risposta corretta di "No". Se voglio scoprire perché no, posso aggiungere un codice più complesso che risponde a domande non originariamente poste qui.
danorton,

0

Ecco una piccola sceneggiatura che ho chiamato test.py. Migliora altri metodi pubblicati in quanto restituirà un codice di errore se uno è impostato e inoltre imposta uno se find non ha elencato alcun file:

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)

Ecco l'output della riga di comando:

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

Quindi, per un risultato in cui find ha avuto errori ma ha trovato file:

$ 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

Quindi, se si desidera l'elenco di file, è possibile utilizzare -print 0passato finde dividere la variabile out su null, oppure è possibile semplicemente aggiungere un'istruzione di stampa per esso.


-1

Non solo findrestituisce i codici di stato di uscita come zero quando ha esito positivo. In unix qualunque sia il comando che esegui, se riesce, restituisce lo stato di uscita come zero.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.