Pregunta

Necesito depender de algunas ejecuciones separadas en un script y no quiero agruparlas todas en una fea declaración 'if'. Me gustaría tomar el código de salida '$?' De cada ejecución y añádelo; al final, si este valor está por encima de un umbral, me gustaría ejecutar un comando.

Pseudocódigo:

ALLOWEDERROR=5

run_something
RESULT=$?
..other things..

run_something_else
RESULT=$RESULT + $?

if [ $RESULT -gt ALLOWEDERROR ] 
   then echo "Too many errors"
fi

Problema: a pesar de que Internet afirma lo contrario, bash se niega a tratar el RESULTADO y $? como entero. ¿Cuál es la sintaxis correcta?

Gracias.

¿Fue útil?

Solución

Es posible que desee echar un vistazo a la trap incorporada para ver si sería útil:

help trap

o

man bash

puedes establecer una trampa para errores como este:

#!/bin/bash

AllowedError=5

SomeErrorHandler () {
    (( errcount++ ))       # or (( errcount += $? ))
    if  (( errcount > $AllowedError ))
    then
        echo "Too many errors"
        exit $errcount
    fi
}

trap SomeErrorHandler ERR

for i in {1..6}
do
    false
    echo "Reached $i"     # "Reached 6" is never printed
done

echo "completed"          # this is never printed

Si cuenta los errores (y solo cuando son errores) como éste en lugar de usar " $? " ;, no tiene que preocuparse por los valores de retorno que no sean cero o uno Un solo valor de retorno de 127, por ejemplo, lo arrojaría por encima de su umbral de inmediato. También puede registrar trap s para otras señales además de ERR .

Otros consejos

Un experimento rápido y sumergirse en información bash dice:

declare -i RESULT=$RESULT + $?

ya que estás agregando al resultado varias veces, puedes usar declarar al inicio, como esto:

declare -i RESULT=0

true
RESULT+=$?
false
RESULT+=$?
false
RESULT+=$?

echo $RESULT
2

que se ve mucho más limpio.

declare -i dice que la variable es un entero.

Alternativamente, puede evitar declarar y usar corchetes de expresiones aritméticas:

RESULT=$(($RESULT+$?))

Utilice la construcción $ ((...)) .

$ cat st.sh
RESULT=0
true
RESULT=$(($RESULT + $?))
false
RESULT=$(($RESULT + $?))
false
RESULT=$(($RESULT + $?))
echo $RESULT
$ sh st.sh
2
$

Para ver cómo agregar números en Bash también vea:

help let 

Si desea utilizar ALLOWEDERROR en su secuencia de comandos, prólogo con un $, por ejemplo, $ ALLOWEDERROR.

Aquí hay algunas formas de realizar una adición en bash o sh:

RESULT=`expr $RESULT + $?`
RESULT=`dc -e "$RESULT $? + pq"`

Y algunos otros solo en bash:

RESULT=$((RESULT + $?))
RESULT=`bc <<< "$RESULT + $?"` 

De todos modos, el estado de salida en caso de error no siempre es 1 y su valor no depende del nivel de error, por lo que en el caso general no tiene mucho sentido verificar una suma de estados contra un umbral.

Como mencionó Mouviciel, recolectar la suma de los códigos de retorno parece bastante absurdo. Probablemente, puede utilizar la matriz para acumular códigos de resultados distintos de cero y verificar su longitud. El ejemplo de este enfoque es el siguiente:

#!/bin/sh

declare RESULT
declare index=0
declare ALLOWED_ERROR=1

function write_result {
    if [ $1 -gt 0 ]; then
        RESULT[index++]=$1
    fi
}

true
write_result $?

false
write_result $?

false
write_result $?

echo ${#RESULT[*]}
if [ ${#RESULT[*]} -gt $ALLOWEDERROR ] 
   then echo "Too many errors"
fi
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top