bash -e udgår, når let eller expr evalueres til 0

Jeg har et bash-script, der indstiller -e, så scriptet afslutter enhver exit-status! = 0 .

Jeg prøver at udføre nogle grundlæggende shell-aritmetikker, der er tildelt variabler, og undertiden er udtrykket lig med 0, hvilket får udgangsstatus for kommandoen let eller expr til at være “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" 

Outputtet 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ørgsmålet er, hvad der er den idiomatiske bash scripting måde at tillade scriptet at mislykkes på reelle exitfejl og ikke på grundlæggende aritmetik, der svarer til 0. Jeg kunne tilføje alle disse udtryk med: div>

Men det virker hacky.

Svar

Brug ikke expr til aritmetik. Det har længe været forældet: Skaller har nu aritmetik indbygget med $((…)) -konstruktionen (POSIX) eller med let indbygget (ksh / bash / zsh) eller ((…)) -konstruktionen (ksh / bash / zsh).

let og ((…)) returnerer 1 (en fejlstatuskode), hvis det sidst evaluerede udtryk er 0. For at undgå dette får dit script til at afslutte under set -e sidste udtryk for ikke at returnere 0, for eksempel:

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

Alternativt kan du bruge || true idiomet:

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

Alternativt kan du gøre din aritmetik inde i $((…)) og dine opgaver udenfor. En opgave returnerer status for den sidste kommandosubstitution i værdien eller 0, hvis der ikke er kommandosubstitution, så du er sikker. Dette har den ekstra fordel at arbejde i en hvilken som helst POSIX-shell (f.eks. Bindestreg).

a=$((2 - 2)) 

Svar

Jeg havde samme problem . tl; dr:

Hvis den sidste ARG [af let] evalueres til 0, skal du returnere 1; lad returnere 0 ellers .

Svar

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

Kommentarer

  • Hvad gør det mere effektivt end at sige (( A = $C - $D ))?

Svar

Denne syntaks fungerer for mig:

a=$((b + c)) 

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *