Tengo como bash shell script con el encabezado #!/bin/bash -e.

Cuando ejecute la secuencia de comandos, se interrumpirá después de la grep comando se ejecuta, pero cuando me quite el parámetro -e, entonces la secuencia de comandos se puede ejecutar normalmente. ¿Cuál es el significado de parámetro -e?

  • Sin embargo, hay no -e opción para bash, por lo tanto, lo que realmente está sucediendo en este caso? 🙁
  • De hecho no es obvio, pero hay una -e opción para bash: serverfault.com/questions/391255/….
  • Sólo un punto más. Por ejemplo, cuando encontramos esto: [ -e filepath ] Devuelve true si el archivo existe.
InformationsquelleAutor Sam Ho | 2012-03-31

2 Comentarios

  1. 88

    La -e opción significa que «si cualquier tubería se termina con un no-cero (‘error’) estado de salida, terminar la secuencia de comandos de inmediato». Desde grep devuelve un estado de salida de 1 cuando no encuentra ninguna coincidencia, se puede causar -e para terminar la secuencia de comandos, incluso cuando no hay un verdadero «error».

    Si quieres mantener el -e opción, pero también tienen un grep comando que podría válidamente no encontrar coincidencias, puede anexar || : a la grep comando. Esto significa que «o, si el grep comando devuelve un valor distinto de cero estado de salida, ejecutar : (que no hace nada)»; por lo que el efecto neto es deshabilitar -e para la grep comando. Así:

    grep PATTERN FILE... || :

    Editado para añadir: El enfoque anterior descarta todos los errores: si grep devuelve 1 porque no encontró los partidos, que es ignorado, pero también si grep devuelve 2 porque hubo un error, que la ignora, y si grep no está en la ruta de acceso (por lo que Bash devuelve 127), que ignorado — y así sucesivamente. Así, en lugar de :, es probablemente mejor usar un comando que comprueba el código de resultado y re-emite el error si es algo que 1. Por ejemplo:

    grep PATTERN FILE || (( $? == 1 ))

    Pero esto destruye el estado de salida; por lo general, cuando un error de comando termina un script en Bash con -e, el script devolverá el comando de salida-estado, pero en el ejemplo anterior, la secuencia de comandos le acabo de volver de 1. Si (y sólo si) nos importa, podemos solucionarlo por escribir algo como esto:

    grep PATTERN FILE || exit_code=$?
    if (( exit_code > 1 )) ; then
        exit $exit_code
    fi

    (primera línea c/o dsummersl‘s comentario).

    A este punto, es probablemente la mejor manera de crear una función de shell para manejar esto por nosotros:

    function grep_no_match_ok () {
        local exit_code
        grep "[email protected]" || exit_code=$?
        return $(( exit_code == 1 ? 0 : exit_code ))
    }

    (nota: el uso de return en lugar de exit, vamos a dejar que -e manejar la salida, cuando corresponda); de esta manera, podemos escribir:

    grep_no_match_ok PATTERN FILE     # won't kill script if no matches are found

    De hecho, ya que lo más probable es que desee utilizar esta función para todos apariciones de grep en esta secuencia de comandos, podemos, de hecho, sólo el nombre de la función grep:

    function grep () {
        local exit_code
        command grep "[email protected]" || exit_code=$?
        return $(( exit_code == 1 ? 0 : exit_code ))
    }
    
    grep PATTERN FILE     # won't kill script if no matches are found

    (nota: el uso de command para la derivación de la función shell dentro de su propio cuerpo: queremos que la función a llamar el programa regular grep, en lugar de buscar recursivamente infinitamente).

    • Muy bonito. Yo he tenido que usar tus consejos para capturar el código de salida para su posterior uso: grep XXX FILE || exitcode=$?. Super útil!
    • Genial, me alegro de que te haya gustado! Tu comentario me ha inspirado para ampliar mi respuesta con algunas mejoras potenciales que usted puede ser que desee.
    • En serio, gracias por eso. El patrón de contorno es esclarecedor; es un buen patrón para defenderse contra la inesperada códigos de salida, mientras que, simultáneamente, ignorando los previstos…definitivamente puedo ver el uso de este patrón para simplificar el flujo principal de mis guiones.
    • Excelente respuesta, el grep función es realmente útil. Gracias.
    • Sólo un punto más. Por ejemplo, cuando encontramos esto: [ -e filepath ] Devuelve true si el archivo existe.
  2. 14

    De la manual:

    Además de la de un solo carácter shell opciones de línea de comandos (ver El Conjunto Builtin), hay varias multi-carácter de las opciones que puede utilizar.

    Y, a continuación, si nos fijamos en lo que set tiene que decir:

    -e

    Salir de inmediato si una tubería (ver Oleoductos), que puede consistir en una simple comando (ver Comandos Simples), un subshell de comandos entre paréntesis (ver Comando de Agrupación), o uno de los comandos que se ejecutan como parte de un comando de la lista delimitada por llaves (ver Comando de Agrupación) devuelve un estado distinto de cero.

    Así que cuando usted dice bash -e, si cualquier comando en el script falla (es decir, devuelve un cero no existe estado), entonces la secuencia de comandos completa inmediatamente falla. Por lo que su grep es devolver un valor distinto de cero porque no es una coincidencia y que apagar toda la secuencia de comandos si se especifica -e cuando se ejecuta bash.

Dejar respuesta

Please enter your comment!
Please enter your name here