Mám bash skript, který nastaví -e, takže skript bude ukončen při jakémkoli stavu ukončení! = 0 .
Snažím se provést nějakou základní aritmetiku prostředí přiřazenou proměnným a někdy je výraz roven 0, což způsobí, že stav ukončení příkazu let nebo expr bude „1“.
Zde je příklad:
#!/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"
Výstup je:
$ ./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"
Můj otázkou je, jaký je idiomatický bash skriptovací způsob, jak umožnit selhání skriptu při skutečných chybách ukončení a ne při základní aritmetice rovné 0. Mohl bych všechny tyto výrazy doplnit o:
A=`expr $C - $D` || true
Ale zdá se to hackerské.
Odpověď
Nepoužívejte expr
pro aritmetiku. Už je to dávno zastaralé: skořápky mají nyní zabudovanou aritmetiku pomocí konstrukce $((…))
(POSIX) nebo pomocí let
vestavěného (ksh / bash / zsh) nebo ((…))
konstrukt (ksh / bash / zsh).
let
a ((…))
vrátit 1 (stavový kód selhání), pokud je poslední vyhodnocený výraz 0. Aby se zabránilo tomu, že by váš skript skončil pod set -e
, zajistěte poslední výraz nevrací 0, například:
let "a = 2 - 2" 1 ((a = 2 - 2, 1))
Případně použijte || true
idiom:
((a = 2 - 2)) || true
Případně proveďte svou aritmetiku uvnitř $((…))
a své úkoly venku. Přiřazení vrátí stav poslední substituce příkazu v hodnotě, nebo 0, pokud není nahrazení příkazu, takže jste v bezpečí. To má další výhodu práce v jakémkoli prostředí POSIX (například pomlčka).
a=$((2 - 2))
Odpověď
Měla jsem stejný problém . tl; dr:
Pokud je poslední ARG [of let] vyhodnocen jako 0, let vrátí 1; let vrátí 0 jinak .
Odpověď
Použít $(( $C - $D ))
místo toho pro vaše aritmatické funkce. Je to také efektivnější.
Komentáře
Odpověď
Tato syntaxe pro mě funguje:
a=$((b + c))
(( A = $C - $D ))
?