Kokonaislukujen vertailu: aritmeettinen lauseke tai ehdollinen lauseke

Bashissa kahta kokonaislukua voidaan verrata ehdollisen lausekkeen avulla

arg1 OP arg2

OP on yksi seuraavista: -eq, -ne, -lt, -le, -gt tai -ge. Nämä aritmeettiset binäärioperaattorit palauttavat arvon tosi, jos arg1 on yhtä suuri, ei yhtä suuri, pienempi, pienempi tai yhtä suuri, suurempi tai suurempi tai yhtä suuri kuin arg2 , vastaavasti. Arg1 ja arg2 voivat olla positiivisia tai negatiivisia kokonaislukuja.

tai aritmeettinen lauseke:

<= >= < > vertailu

== != tasa-arvo ja eriarvoisuus

Miksi meillä on kaksi erilaista tapaa verrata kahta kokonaislukua? Milloin mitä käyttää?

Esimerkiksi [[ 3 -lt 2 ]] käyttää ehdollista lauseketta ja (( 3 < 2 )) aritmeettista lauseketta. Molemmat palauttavat 0, kun vertailu on totta.

Voidaanko näitä kahta menetelmää käyttää aina keskenään vaihdettaessa kahta kokonaislukua? Jos kyllä, miksi Bashilla on kaksi menetelmää eikä yksi?

Kommentit

  • = != < <= > >= vertaa merkkijonoja . 1 -eq 01 mutta 1 != 01 ja 8 -lt 42 mutta 8 > 42
  • Ne ovat ylikuormitettuja aritmeettisissa lausekkeissa.
  • sinun ’ sinun on etsittävä bashin muutoslokista selvittääksesi, milloin kukin ominaisuus on lisätty. Epäilen, että aritmeettiset lausekkeet lisättiin paljon myöhemmin kuin testikomento.
  • En kysy merkkijonojen vertailusta. @muru.

Vastaa

Kyllä, meillä on kaksi erilaista tapaa verrata kahta kokonaislukua.

Näyttää siltä, että näitä tosiasioita ei hyväksytä laajalti tällä foorumilla:

  1. Idioomin sisällä [ ] operaattorit aritmeettiseen vertailuun ovat -eq, -ne, -lt, -le, -gt ja -ge.

    Koska ne ovat myös testikomennon sisällä ja [[ ]].

    Kyllä tässä idioomissa, =, < jne. Ovat merkkijonooperaattorit.

  2. Idioomin (( )) sisällä aritmeettisen vertailun operaattorit ovat == , !=, <, <=, > ja >=.

    Ei, tämä ei ole aritmi etiikkalaajennus ”(joka alkaa $) nimellä $(( )). Se on määritelty ”yhdistetyksi komennoksi” man bash: ssa.

    Kyllä, se noudattaa samoja sääntöjä (sisäisesti) aritmeettisesta laajennuksesta, mutta sillä ei ole lähtöä, vain poistumisarvo. Sitä voidaan käyttää näin:

if (( 2 > 1 )); then ... 

Miksi meillä on kaksi erilaista tapaa verrata kahta kokonaislukua?

Luulen, että jälkimmäinen (( )) kehitettiin yksinkertaisempana tapana suorittaa aritmeettiset testit. Se on melkein sama kuin $(( )), mutta sillä ei vain ole lähtöä.

Miksi kaksi? Sama kuin miksi meillä on kaksi printf (ulkoinen ja sisäänrakennettu) tai neljä testiä (ulkoinen test, sisäänrakennettu test, [ ja [[). Tällä tavoin kuoret kasvavat, parantamalla jotakin pinta-alaa yhden vuoden aikana, parantaen toista seuraavana vuonna.

Milloin mitä käyttää?

Se on erittäin vaikea kysymys, koska ei pitäisi olla tehokasta eroa. Tietysti [ ] -työn ja (( )) -työn sisäisessä toiminnassa on joitain eroja, mutta kumpi on parempi verrata kahta kokonaislukua? Mikä tahansa !.

Voidaanko näitä kahta menetelmää verrata kahta kokonaislukua aina vaihdettavasti?

Kahden numeron osalta minun on pakko sanoa kyllä.
Mutta muuttujien, laajennusten osalta , matemaattisissa operaatioissa voi olla keskeisiä eroja, joiden tulisi suosia yhtä tai toista. En voi sanoa, että ehdottomasti molemmat ovat tasa-arvoisia. Ensinnäkin (( )) voisi suorittaa useita matemaattisia operaatioita peräkkäin:

if (( a=1, b=2, c=a+b*b )); then echo "$c"; fi 

Jos kyllä, miksi Bashilla on kaksi menetelmää yhden sijaan?

Jos molemmat ovat hyödyllisiä, miksi ei ?.

Kommentit

  • = on tehtävä ja == on vertailu aritmeettisissa laajennuksissa. Kysymys lainaa sitä oikein. Mutta vastaus on väärä.
  • Myöskään ( ei ole varattu sana bashissa, joten välilyöntejä (( ympärille ei tarvitse asettaa [ tai [[

vastaus

Historiallisesti test -komento oli ensin (ainakin takaisin Unixin seitsemäs painos vuonna 1979). Se käytti operaattoreita = ja != merkkijonojen vertaamiseen ja -eq, -ne, -lt jne. Lukujen vertaamiseksi. Esimerkiksi test 0 = 00 on väärä, mutta test 0 -eq 00 on totta. En tiedä miksi tämä syntakse valittiin, mutta sen on ehkä vältetty käyttämästä komentoja < ja >, jotka kuorella olisi jäsennetty uudelleenohjausoperaattoreiksi. test -komento sai uuden syntaksin muutama vuosi myöhemmin: [ … ] vastaa test ….

Ehdollinen syntaksin [[ … ]], jonka sisällä < ja > voidaan käyttää operaattoreina ilman lainausta, lisättiin myöhemmin, ksh: ssä. Se säilytti taaksepäin yhteensopivuuden [ … ] kanssa, joten käytti samoja operaattoreita, mutta lisäsi < ja > merkkijonojen vertaamiseksi (esimerkiksi [[ 9 > 10 ]] mutta [[ 9 -lt 10 ]]). Lisätietoja on kohdassa yksi- tai kaksoissulkeella – bash

Aritmeettiset lausekkeet tulivat myös myöhemmin kuin test -komento,

Korn-kuoressa , jossain vaiheessa 1980-luvulla. He seurasivat C-kielen syntaksia, joka oli erittäin suosittu Unix-piireissä. Siksi he käyttivät C: n operaattoreita:==tasa-arvoon,<=vähemmän tai yhtä paljon jne.

Unixin seitsemännellä painoksella ei ollut aritmeettisia lausekkeita, mutta sillä oli expr -komento , joka myös toteutti C-tyyppinen syntaksin kokonaislukuoperaatioille, mukaan lukien sen vertailuoperaattorit. Shell-komentosarjassa merkit < ja > oli lainattava niiden suojaamiseksi kuorelta, esim. if expr 1 \< 2; … vastaa if test 1 -lt 2; …. Aritmeettisten lausekkeiden lisääminen kuoreen teki useimmista expr -tyyppien käytöstä vanhentuneen, joten sitä ei tunneta tänään.

Sh-skriptissä sinä ” d käyttää yleensä aritmeettisia lausekkeita kokonaisluvun laskemiseen ja [ … ] kokonaislukujen vertaamiseen.

if [ "$((x + y))" -lt "$z" ]; then … 

Ksh: ssä , bash- tai zsh-komentosarja, voit käyttää ((…)) molemmille.

if ((x + y < z)); then … 

[[ … ]] -lomake on hyödyllinen, jos haluat käyttää ehtoja, jotka sisältävät muita asioita kuin kokonaislukuja.

Vastaa

testin man-sivua = ja! = käytetään merkkijonovertailuissa, kun taas lausekkeet -eq, -gt, -lt, -ge, -le ja -ne ovat kokonaislukuvertailuja. Olen aina noudattanut tätä käytäntöä kirjoittaessani komentosarjoja ja se toimii aina. Huomaa, että jos lausekkeessa on muuttujia, sinun on ehkä lainattava muuttujia jollakin tavalla, jotta vältetään nollavertailu.

Paperilla teemme merkkijonojen / numeroiden vertailuja ilman paljon miettimistä. Toisaalta tietokone ei tiedä, onko 987 luku tai merkkijono. Tarvitset eri operaattoreiden kertomaan tietokoneelle, mitä tehdä, jotta saat oikean tuloksen. täällä on joitain lisätietoja, jotka selittävät osan historiasta. Pohjimmiltaan muuttujat ovat avaamattomia ja pysyneet sellaisina historiallisen yhteensopivuuden kannalta.

Kommentit

  • Viestissäni = ja != ovat aritmeettisia operaattoreita, kun taas test -sivulla näkyvät vain ehdolliset lausekeoperaattorit.

Vastaa

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