bash -e ukončí, když se let nebo expr vyhodnotí na 0

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

  • Díky čemu je efektivnější než říkat (( A = $C - $D ))?

Odpověď

Tato syntaxe pro mě funguje:

a=$((b + c)) 

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *