bash -e sale cuando let o expr se evalúa como 0

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

  • ¿Qué lo hace más eficiente que decir (( A = $C - $D ))?

Respuesta

Esta sintaxis me funciona:

a=$((b + c)) 

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *