modismo `set -e` y` grep` para evitar la salida prematura del script de shell cuando no se encuentra el patrón

15

Se requiere ayuda: en el contexto de los scripts de shell en un bash de GNU / LINUX:

Yo siempre uso set -e. A menudo, me gustaría grepy no siempre quiero que la secuencia de comandos termine la ejecución si greptiene un estado de salida de 1indicación de patrón no encontrado.

Algunas cosas que he tratado de resolver este problema son las siguientes:

(Intente I)
Si set +o pipefaile invoco grep con algo así grep 'p' | wc -l, obtengo el comportamiento deseado hasta que un futuro mantenedor lo habilite pipefail. Además, me gusta habilitar pipefailpara que esto no funcione para mí.

(Intente II)
Use un sedo awksolo patrón de coincidencia de líneas de impresión, luego wclíneas coincidentes para probar el patrón coincidente. No me gusta esta opción porque usar sedto grepparece una solución para mi verdadero problema.

(Prueba III)
Este es mi menos favorito, algo como:set +e; grep 'p'; set-e

Cualquier idea / modismos sería muy apreciada, gracias.

Yeow_Meng
fuente

Respuestas:

19

Puede poner el grep en una ifcondición, o si no le importa el estado de salida, agregue || true.

Ejemplo: grepmata el caparazón

$ bash
$ set -e
$ echo $$
33913
$ grep foo /etc/motd
$ echo $$
9233

solución 1: descartar el estado de salida distinto de cero

$ bash
$ set -e
$ echo $$
34074
$ grep foo /etc/motd || true
$ echo $$
34074

Solución 2: prueba explícitamente el estado de salida

$ if ! grep foo /etc/motd; then echo not found; fi
not found
$ echo $$
34074

Desde la página de manual de bash discutiendo set -e:

El shell no sale si el comando que falla es parte de la lista de comandos inmediatamente después de un tiempo o hasta la palabra clave, parte de la prueba después de las palabras reservadas if o elif , parte de cualquier comando ejecutado en una lista && o ││ excepto el comando después del && o ││ final , cualquier comando en una tubería pero el último, o si el valor de retorno del comando se está invirtiendo con ! .

Glenn Jackman
fuente
Dado que bash durante mucho tiempo no implementó -e correctamente, es posible que la documentación aún no sea correcta. Como el texto parece ser idéntico a la página de manual de bash-3.x, tenga en cuenta que todas las versiones de bash anteriores a bash4.0 implementaron -e incorrectamente.
schily
También tenga en cuenta que, como el estándar POSIX también era incorrecto, cambiamos el texto POSIX para el manejo de errores con -e en 2009
schily
1
@schily Indique dónde se puede encontrar cuál es el comportamiento 'correcto' de -e, qué bash <4 hizo de manera diferente y qué cambió en POSIX.
zwol
Los errores en bash-3 básicamente lo hacen inutilizable, makeya que no siempre sale por errores. Para las discusiones POSIX relacionadas, puede consultar austingroupbugs.net
schily
@schily ¿Podrías ser más específico?
zwol