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
Svar
Denna syntax fungerar för mig:
a=$((b + c))
(( A = $C - $D ))
?