bash -e går ut när let eller expr utvärderas till 0

Jag har ett bash-skript som ställer in -e så att skriptet kommer att avslutas vid vilken utgångsstatus som helst! = 0 .

Jag försöker göra någon grundläggande skal-aritmetik som tilldelats variabler och ibland är uttrycket lika med 0 vilket gör att utgångsstatusen för kommandot let eller expr är ”1”.

Här är ett exempel:

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

Utgången är:

$ ./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 frågan är vad det idiomatiska bash-skriptsättet är för att tillåta skriptet att misslyckas vid verkliga utgångsfel och inte på grundläggande aritmetik som motsvarar 0. Jag skulle kunna suffixa alla dessa uttryck med: div>

Men det verkar hackigt.

Svar

Använd inte expr för aritmetik. Det har länge varit föråldrat: skal har nu inbyggd aritmetik med $((…)) -konstruktionen (POSIX) eller med let inbyggd (ksh / bash / zsh) eller ((…)) -konstruktionen (ksh / bash / zsh).

let och ((…)) returnera 1 (en felkod för status) om det senast utvärderade uttrycket är 0. För att undvika att ditt skript avslutas under set -e sista uttrycket för att inte returnera 0, till exempel:

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

Alternativt kan du använda || true idiom:

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

Alternativt gör din aritmetik inuti $((…)) och dina uppgifter utanför. En uppgift returnerar statusen för den senaste kommandosubstitutionen i värdet, eller 0 om det inte finns någon kommandosubstitution, så du är säker. Detta har den extra fördelen att du arbetar i alla POSIX-skal (som bindestreck).

a=$((2 - 2)) 

Svar

Jag hade samma problem . tl; dr:

Om den sista ARG [av let] utvärderas till 0, låt returnera 1; låt returnera 0 annars .

Svar

Använd $(( $C - $D )) istället för din aritmatik. Det är också effektivare.

Kommentarer

  • Vad gör det mer effektivt än att säga (( A = $C - $D ))?

Svar

Denna syntax fungerar för mig:

a=$((b + c)) 

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *