Usando grep con tubería y ampersand para filtrar errores de find

22

Estoy usando cygwin para encontrar un archivo en el cygdrive.

Sin embargo, necesito suprimir los mensajes de permiso denegado (de lo contrario, los resultados se ocultan en los mensajes de error). El siguiente comando funciona:

find -name 'myfile.*' |& grep -v "Permission denied"

No entiendo por qué el ampersand necesita ser puesto en este comando, hubiera esperado que esto funcionara, pero no lo hace.

find -name 'myfile.*' | grep -v "Permission denied"

Por favor explique el significado del signo "&".

Henrik K
fuente

Respuestas:

24

En los sistemas tipo Unix, hay dos rutas de salida que, si no se modifican, enviarán la salida a la pantalla. El error estándar (o stderr) es el que captura la mayoría de las fallas y condiciones de error.

Para pasar el mensaje de permiso denegado en stderr a la misma secuencia de salida como "salida normal", debe combinar los dos. En su ejemplo, para grep -vque funcione correctamente, combina stdout (salida estándar) y stderr con la sintaxis arcana que ve.

Del manual GNU Bash sección 3.2.2 Tuberías :

Si ' |&' se utiliza, command1 Es error estándar, además de su salida estándar, está conectado a command2 ‘s de entrada estándar a través de la tubería; es taquigrafía para 2>&1 |. Esta redirección implícita del error estándar a la salida estándar se realiza después de cualquier redirección especificada por el comando.

Además, como señala geirha, si solo desea deshacerse de la salida stderr, querría hacer algo como

find -name 'myfile.*' 2> /dev/null

o quizás

find -name 'myfile.*' 2> /tmp/errorlog

Y tenga en cuenta que si tiene cadenas de comandos, como findpasar su salida a xargsusted, necesitaría poner toda la tubería de comandos entre paréntesis para capturar la salida de todos los componentes del comando. P.ej,

(find | egrep ^[RS].[0-9]+/.svg] | xargs head -1 )  2> /dev/null

Si omitió los paréntesis e hizo esto en su lugar,

find | egrep ^[RS].[0-9]+/.svg] | xargs head -1 2> /dev/null

aún vería errores de permiso denegado de find o egrep, pero stderr sería redirigido para xargs.

Como has visto, es probable que deseches el stderr solo después de ver su contenido durante una ejecución de prueba.

Tenga en cuenta que con GNU findy hasta donde puedo decir, cualquier compatible con POSIX find, la -printopción es implícita. Todavía puede suministrarlo explícitamente si lo desea.

belacqua
fuente
Parece ser solo bash4 + wiki.bash-hackers.org/bash4#redirection
Luke Exton
1
@LukeExton Sí. En otros shells, 2>&1 |se puede usar en lugar de |&(es decir, se puede redirigir explícitamente stderr a stdout y luego canalizar eso al siguiente comando en la tubería).
Eliah Kagan
2> >( grep filter )también es útil
user1133275