Minä työskentelen Bash 3: n kanssa ja yritän muodostavat ehdollisen. C / C ++: ssa sen kuollut yksinkertainen: ((A || B) && C)
. Bashissa se ei osoittautunut niin (mielestäni Git-kirjoittajien on täytynyt antaa tämä koodi ennen kuin he siirtyivät muihin pyrkimyksiin).
Tämä ei toimi. Huomaa, että <0 or 1>
ei ole merkkijonon kirjain; se tarkoittaa 0 tai 1 (yleensä tulee grep -i
).
A=<0 or 1> B=<0 or 1> C=<0 or 1> if [ [ "$A" -eq "0" ] || [ "$B" -ne "0" ] ] && [ "$C" -eqe "0" ]; then ... fi
Tuloksena on
line 322: syntax error near unexpected token `[["
Yritin sitten:
A=<0 or 1> B=<0 or 1> C=<0 or 1> if [ ([ "$A" -eq "0" ]) || ([ "$B" -ne "0" ]) ] && [ "$C" -eq "0" ]; then ... fi
tuloksena on:
line 322: syntax error near unexpected token `[["
Osa ongelmasta on, että hakutulokset ovat triviaalisia esimerkkejä eivätkä monimutkaisempia esimerkkejä yhdistetyillä ehdollisilla.
Kuinka suoritan yksinkertaisen ((A || B) && C)
Bashissa?
Olen valmis vain avaamaan sen ja toistamaan samat komennot useissa lohkoissa:
A=<0 or 1> B=<0 or 1> C=<0 or 1> if [ "$A" -eq "0" ] && [ "$C" -eq "0" ]; then ... elif [ "$B" -ne "0" ] && [ "$C" -eq "0" ]; then ... fi
Vastaus
Bashin syntaksit eivät ole C: n kaltaisia, vaikka pieni osa siitä olisi C: n innoittama. Et voi yksinkertaisesti yrittää kirjoittaa C-koodia ja odottaa sen toimivan.
Kuoren pääkohde on komentojen suorittaminen. Open-bracket-komento [
on komento, joka suorittaa yhden testin¹. Voit jopa kirjoittaa sen nimellä test
(ilman viimeistä sulkeutta). ||
– ja &&
-operaattorit ovat kuorioperaattoreita, ne yhdistävät komentoja eivätkä testejä.
Joten kirjoittaessasi
[ [ "$A" -eq "0" ] || [ "$B" -ne "0" ] ] && [ "$C" -eq "0" ]
se on jäsennelty nimellä
[ [ "$A" -eq "0" ] || [ "$B" -ne "0" ] ] && [ "$C" -eq "0" ]
mikä on sama kuin
test [ "$A" -eq "0" || test "$B" -ne "0" ] && test "$C" -eq "0"
Huomaa epäsymmetriset sulkeet? Joo, se ei ole hyvä. Sulkuyritykselläsi on sama ongelma: väärät hakasulkeet.
Kommenttien ryhmittelemisen syntaksi on aaltosulkeja. Aaltosulkujen jäsentäminen vaatii täydellisen komennon ennen niitä, joten sinun on lopetettava komento aaltosulkeissa uudella rivillä tai puolipisteellä.
if { [ "$A" -eq "0" ] || [ "$B" -ne "0" ]; } && [ "$C" -eq "0" ]; then …
Siellä ”vaihtoehtoinen tapa käyttää kaksoissulkeita. Toisin kuin yksittäiset suluissa, kaksoissulkeet ovat erityisiä kuoren syntaksia. Ne rajaavat ehdolliset lausekkeet . Tuplasulkeiden sisällä voit käyttää sulkeita ja operaattoreita, kuten &&
ja ||
. Koska kaksoissulkeet ovat kuoren syntaksia, kuori tietää, että kun nämä operaattorit ovat suluissa, ne ovat osa ehdollisen lausekkeen syntaksia, eivät osa tavallista komentokomennon syntaksia.
if [[ ($A -eq 0 || $B -ne 0) && $C -eq 0 ]]; then …
Jos kaikki testisi ovat numeerisia, on olemassa toinenkin tapa, joka rajaa artehmeettiset lausekkeet . Aritmeettiset lausekkeet suorittavat kokonaislukulaskennat hyvin C-tyyppisellä syntaksilla.
if (((A == 0 || B != 0) && C == 0)); then …
Löydät bash-haarukan pohjamaali hyödyllinen.
[
voidaan käyttää tavallisessa muodossa. [[
ja ((
ovat ominaisia bashille (ja ksh: lle ja zsh: lle).
¹ Se voi myös Yhdistä useita testejä loogisten operaattoreiden kanssa, mutta tämä on hankala käyttää ja sillä on hienovaraisia sudenkuoppia, joten en selitä sitä.
Kommentit
vastaus
Käytä [[
:
if [[ ( "$A" -eq "0" || "$B" -ne "0" ) && "$C" -eq "0" ]]; then ...
Jos haluat [
, seuraavat toimet toimivat:
if [ \( "$A" -eq "0" -o "$B" -ne "0" \) -a "$C" -eq "0" ]; then ...
Kommentit
- Kiitos, Stephen. Minun tapauksessani käytin ensimmäistä esimerkkiäsi näin … regex = ' ^ [0-9] + $ ' length = $ {#datearg} jos! [[$ datearg = ~ $ regex & & $ pituus -eq 8]]; sitten echo " -virhe: Ei lukumäärää 8 "; fi
Vastaa
Käytä -o
-operaattoria sisäkkäin ||. Voit myös käyttää -a
-merkkiä korvaamaan & &, jos tarpeen muissa lausunnoissa. .
EXPRESSION1 -a EXPRESSION2 both EXPRESSION1 and EXPRESSION2 are true EXPRESSION1 -o EXPRESSION2 either EXPRESSION1 or EXPRESSION2 is true if [ "$A" -eq "0" -o "$B" -ne "0" ] && [ "$C" -eq "0" ]; then echo success;fi
Kommentit
- Kiitos. Löysin
-a
ja-o
, mutta en kokeillut niitä. Joku Stack Overflow -sivustolla sanoi välttävän sitä. Olen enimmäkseen samaa mieltä heidän kanssaan, koska käsikirjoitus on vähemmän luettavissa niiden avulla. - … mutta siirrettävämpi.
- @Kusalananda – Kiitos siirrettävyydestä. Komentosarjan on suoritettava järjestelmissä, joissa on Bash 2 – Bash 4. Onko
[[ ( "$A" -eq "0" || "$B" -ne "0" ) && "$C" -eq "0" ]]
heillä ongelmia? - Ei ongelmia ole niin kauan kuin jatkat
bash
tai mikä tahansa muu kuori, joka ymmärtää[[ ... ]]
. - -Käytön alaosa on se, että se ei ' t oikosulku, jos ensimmäinen lauseke on väärä. Joten jos luotat oikosulkuun estämään mahdollisen kohtalokkaan toisen lausekkeen suorittamisen, et voi käyttää -a. Esimerkki: pastebin.com/zM77TXW1
[[ … ]]
lisättiin bashissa 2.02.((…))
lisättiin bash 2.0: een.||
ja vaihda arvosta[
arvoon[[
ja((
. Yhtäläinen etusija[
-ohjelmassa (käytä sulkeita ohjaamaan arvioinnin järjestystä), mutta & & on suurempi etusija[[
: ssä ja((
kuin||
(kuten kohdassa C).[[ … ]]
tai$((…))
ovat vain ryhmittelyä varten.