bash -e går ut når let eller expr evalueres til 0

Jeg har et bash-skript som setter -e slik at skriptet går ut på hvilken som helst utgangsstatus! .

Jeg prøver å gjøre noe grunnleggende skall-aritmetikk tildelt variabler, og noen ganger er uttrykket lik 0, noe som fører til at utgangsstatusen for kommandoen let eller expr er «1».

Her er et eksempel:

#!/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" 

Utgangen er:

$ ./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" 

Min spørsmålet er hva som er den idiomatiske bash-skriptsmåten for å tillate at skriptet mislykkes på virkelige utgangsfeil og ikke på grunnleggende aritmetikk som tilsvarer 0. Jeg kunne suffiksere alle disse uttrykkene med:

A=`expr $C - $D` || true 

Men det virker hakket.

Svar

Ikke bruk expr for regning. Det har lenge vært foreldet: skjell har nå innebygd aritmetikk, med $((…)) -konstruksjonen (POSIX), eller med let innebygd (ksh / bash / zsh) eller ((…)) konstruksjonen (ksh / bash / zsh).

let og ((…)) returnerer 1 (en feilstatuskode) hvis det siste evaluerte uttrykket er 0. For å unngå at dette fører til at skriptet ditt avsluttes under set -e, sørg for siste uttrykk for ikke å returnere 0, for eksempel:

let "a = 2 - 2" 1 ((a = 2 - 2, 1)) 

Alternativt kan du bruke || true idiom:

((a = 2 - 2)) || true 

Alternativt kan du gjøre regningen din inne i $((…)) og oppgavene dine utenfor. En oppgave returnerer statusen for den siste kommandosubstitusjonen i verdien, eller 0 hvis det ikke er kommandosubstitusjon, så du er trygg. Dette har den ekstra fordelen av å jobbe i et POSIX-skall (for eksempel bindestrek).

a=$((2 - 2)) 

Svar

Jeg hadde samme problem . tl; dr:

Hvis den siste ARG [av la] evalueres til 0, la retur 1; la returnerer 0 ellers .

Svar

Bruk $(( $C - $D )) i stedet for din regning. Det er også mer effektivt.

Kommentarer

  • Hva gjør det mer effektivt enn å si (( A = $C - $D ))?

Svar

Denne syntaksen fungerer for meg:

a=$((b + c)) 

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *