Tengo un script bash que establece -e para que el script salga en cualquier estado de salida! = 0 .
Estoy intentando hacer aritmética básica de shell asignada a variables y, a veces, la expresión es igual a 0, lo que hace que el estado de salida del comando let o expr sea «1».
Aquí hay un ejemplo:
#!/bin/bash -ex echo "Test 1" Z=`expr 1 - 1` || true echo "Z will print" let "A=4 - 4" echo "A WILL NEVER PRINT $A" Y=`expr 1 - 1` echo "Y WILL NEVER PRINT $Y" X=$(expr 2 - 2) echo "X WILL NEVER PRINT $X"
El resultado es:
$ ./test_error.sh + echo "Test 1" Test 1 ++ expr 1 - 1 + Z=0 + true + echo "Z will print" Z will print + let "A=4 - 4"
Mi La pregunta es cuál es la forma idiomática de la secuencia de comandos bash para permitir que la secuencia de comandos falle en errores de salida reales y no en aritmética básica igual a 0. Podría agregar el sufijo a todas esas expresiones con:
A=`expr $C - $D` || true
Pero eso parece hacky.
Respuesta
No use expr
para aritmética. Ha sido obsoleto durante mucho tiempo: los shells ahora tienen aritmética incorporada, con la construcción $((…))
(POSIX), o con let
incorporado (ksh / bash / zsh) o la construcción ((…))
(ksh / bash / zsh).
let
y ((…))
devuelve 1 (un código de estado de falla) si la última expresión evaluada es 0. Para evitar que esto haga que su secuencia de comandos salga bajo set -e
, organice el la última expresión no devuelve 0, por ejemplo:
let "a = 2 - 2" 1 ((a = 2 - 2, 1))
Alternativamente, use el || true
modismo:
((a = 2 - 2)) || true
Alternativamente, haga su aritmética dentro de $((…))
y sus asignaciones fuera. Una asignación devuelve el estado de la última sustitución de comando en el valor, o 0 si no hay sustitución de comando, por lo que está seguro. Esto tiene el beneficio adicional de trabajar en cualquier shell POSIX (como el guión).
a=$((2 - 2))
Respuesta
Tenía el mismo problema . tl; dr:
Si el último ARG [de let] se evalúa a 0, let devuelve 1; let devuelve 0 en caso contrario .
Responder
Utilice $(( $C - $D ))
en su lugar para su aritmática. También es más eficiente.
Comentarios
Respuesta
Esta sintaxis me funciona:
a=$((b + c))
(( A = $C - $D ))
?