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
-aja-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
bashtai 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.