¿Puedo hacer que `find` return no sea 0 cuando no se encuentran archivos coincidentes?


46

Incluso cuando /tmpno se ha llamado ningún archivo something, al buscarlo findse devolverá 0:

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

¿Cómo puedo obtener un estado de salida distinto de cero cuando findno encuentro nada?

Respuestas:


44

Aquí hay una frase que creo que hace lo que quieres:

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

El estado de retorno será 0cuando se encuentre algo y, de lo contrario, no será cero.

Si también necesita capturar la salida de findpara un procesamiento posterior, la respuesta de Sven lo ha cubierto.


14
El seguimiento *de la egrepexpresión regular es completamente redundante. Puesto que no se está utilizando egrepla sintaxis de expresiones regulares, el viejo y simple greppuede haber algunos microsegundos más rápido.
tripleee

aprendí a usarfind ... | read
Sam

14

La solución más simple que no imprime, pero sale 0 cuando se encuentran resultados

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

2
Las comillas dobles no sirven para nada aquí.
haridsv

Si bien las comillas dobles no tienen función de código, sí aclaran al lector que el carácter de punto es una expresión regular y no un directorio.
Dharma Bellamkonda

13

La salida 0 es fácil con find, la salida> 0 es más difícil porque eso generalmente solo ocurre con un error. Sin embargo, podemos hacer que suceda:

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

2
Por lo que puedo decir, esto no funciona. El código de salida de findno parece depender de los códigos de salida de ninguno de los -execs que ejecutó.
Chris

@Chris funciona para mí y los 4 que votaron
Steven Penny,

ejemplo de resultado erróneamente falso de esta solución: find / existentes-punto-inicial / no-existente-punto-inicial -name archivo-en-existente-punto-inicial -exec falso {} +
Gerald Schade

2
Esto funciona correctamente y está documentado (aunque oculto en la execsección, no bajo el valor de retorno). No puede diferenciar entre nada encontrado y encontrarse con errores (por ejemplo, cuando se invocó en un punto de partida inexistente).
Tgr

Si necesita esta funcionalidad - sí
Gerald Schade

7

Después de encontrar esta pregunta mientras trataba de encontrar la manera de resolver un problema con Puppet (cambiar los permisos en las carpetas de un directorio pero no en el directorio en sí), esto parece funcionar:

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

Mi caso de uso específico es este:

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

Que saldrá del código 1 si el comando find no encuentra archivos con los permisos requeridos.


Algunas soluciones (no las probé todas) aquí no funcionaron en una Mac; Esto lo hizo.
Alex Hall

5

No es posible. Find devuelve 0 si sale con éxito, incluso si no encontró un archivo (que es un resultado correcto que no indica un error cuando el archivo no existe).

Para citar la página de búsqueda

ESTADO DE SALIDA

buscar salidas con estado 0 si todos los archivos se procesan correctamente, mayor que 0 si se producen errores. Esta es deliberadamente una descripción muy amplia, pero si el valor de retorno no es cero, no debe confiar en la exactitud de los resultados de find.

Dependiendo de lo que desee lograr, podría intentar dejar encontrar -printel nombre de archivo y probarlo con su salida:

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

Ciertamente es posible , aunque no tan robusto como uno podría desear.
Ruslan

La página del manual está mal organizada; lo que dijo Ruslan está documentado bajo la opción exec/ execdir(usado con +):If any invocation returns a non-zero value as exit status, then find returns a non-zero exit status.
Tgr

1

Siento que este es el método más conciso y directo:

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

2
En este caso, si find tiene un error, imprimirá el resultado en / dev / null, devolverá una salida distinta de cero y luego el comando de prueba lo fijará a 0.
Jeff Ferland

No creo que sea verdad. Por favor describa su ejemplo. Si hay un error y encuentra salidas, la cadena estará vacía y la prueba devolverá un valor distinto de cero.
danorton

No estoy seguro de cuál podría ser su ejemplo, pero omití accidentalmente -print -quit, lo que podría abordar su preocupación.
danorton

¿Quizás la otra persona que votó en contra (presumiblemente por la misma razón) puede proporcionar un ejemplo contrario?
danorton

1
Está bien, simplemente no te gusta mi estilo. Para mis casos de uso, cualquier error que se encuentre puede ser ruidoso o tan grave que aparecerán en otro lugar. En cualquier caso, este método responde correctamente la última pregunta: "¿Hay un archivo accesible en la ruta por el nombre?" Un error devolverá una respuesta correcta de "No". Si quiero averiguar por qué no, puedo agregar un código más complejo que responda preguntas que originalmente no se plantearon aquí.
danorton

0

Aquí hay un pequeño guión que llamé test.py. Mejora con respecto a otros métodos publicados, ya que devolverá un código de error si se establece uno, y además establece uno si find no enumera ningún archivo:

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)

Aquí está la salida de la línea de comandos:

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

Luego, para un resultado donde find tenía errores pero encontró archivos:

$ 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

Luego, si desea la lista de archivos, puede hacer uso de -print 0pasar findy dividir la variable en nulos, o simplemente puede agregarle una declaración de impresión.


-1

No es solo findque devuelve los códigos de estado de salida como cero cuando tiene éxito. En unix, cualquiera que sea el comando que ejecute, si tiene éxito, devuelve el estado de salida como cero.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.