bash -e poistuu, kun let tai expr arvioi arvon 0

Minulla on bash-komentosarja, joka asettaa -e, joten komentosarja poistuu millä tahansa poistumistilalla! = 0 .

Yritän tehdä muuttujille määritetyn peruskuoren aritmeettisen ja joskus lauseke on 0, mikä saa let- tai expr-komennon poistumistilaksi ”1”.

Tässä on esimerkki:

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

Lähtö on:

$ ./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" 

Oma kysymys on mikä on idiomaattinen bash-komentosarjojen tapa antaa komentosarjan epäonnistua todellisissa poistumisvirheissä eikä perusaritmeettisessa yhtälössä 0. Voisin liittää kaikki nämä lausekkeet:

A=`expr $C - $D` || true 

Mutta se tuntuu hakkeroinnilta.

Vastaa

Älä käytä expr laskennalle. Se on pitkään ollut vanhentunut: kuoriin on nyt rakennettu aritmeettinen rakenne, jossa on $((…)) -rakenne (POSIX) tai sisäänrakennettu let (ksh / bash / zsh) tai ((…)) -rakenne (ksh / bash / zsh).

let ja ((…)) palauta 1 (vikatilakoodi), jos viimeksi arvioitu lauseke on 0. Jotta tämä ei aiheuttaisi komentosarjan poistumista set -e -kohdasta, järjestä viimeinen lauseke ei palauta 0, esimerkiksi:

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

Vaihtoehtoisesti voit käyttää || true idioomia:

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

Vaihtoehtoisesti voit suorittaa aritmeettisen arvon $((…)) ja tehtäviesi ulkopuolella. Tehtävä palauttaa arvon viimeisen komentokorvauksen tilan tai 0, jos komentoa ei ole, joten olet turvassa. Tästä on lisäetuna työskennellä missä tahansa POSIX-kuoressa (kuten viiva).

a=$((2 - 2)) 

vastaus

Minulla oli sama ongelma . tl; dr:

Jos viimeinen ARG: n arvo on 0, anna palauttaa 1; anna palauttaa muuten .

Vastaa

Käytä $(( $C - $D )) sen sijaan aritmaattiselle. Se on myös tehokkaampi.

Kommentit

  • Mikä tekee siitä tehokkaamman kuin sanoa (( A = $C - $D ))?

vastaus

Tämä syntaksi toimii minulle:

a=$((b + c)) 

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *