Sammenligning af heltal: aritmetisk udtryk eller betinget udtryk

I Bash kan to heltal sammenlignes ved hjælp af betinget udtryk

arg1 OP arg2

OP er en af -eq, -ne, -lt, -le, -gt eller -ge. Disse aritmetiske binære operatorer returnerer sandt, hvis arg1 er lig med, ikke lig med, mindre end, mindre end eller lig med, større end eller større end eller lig med arg2 , henholdsvis. Arg1 og arg2 kan være positive eller negative heltal.

eller aritmetisk udtryk:

<= >= < > sammenligning

== != lighed og ulighed

Hvorfor har vi to forskellige måder at sammenligne to heltal på? Hvornår skal man bruge hvilket?

For eksempel bruger [[ 3 -lt 2 ]] betinget udtryk, og (( 3 < 2 )) bruger aritmetisk udtryk. Begge returnerer 0, når sammenligningen er sand

Kan disse to metoder altid bruges om hinanden, når man sammenligner to heltal? Hvis ja, hvorfor har Bash to metoder i stedet for en?

Kommentarer

  • = != < <= > >= sammenlign strenge . 1 -eq 01 men 1 != 01 og 8 -lt 42 men 8 > 42
  • De er overbelastet i aritmetiske udtryk.
  • du ‘ Du bliver nødt til at søge i bash-ændringslogene for at finde ud af, hvornår hver funktion var tilføjet. Jeg formoder, at de aritmetiske udtryk blev tilføjet meget senere end testkommandoen.
  • Jeg spørger ikke om at sammenligne strenge. @muru.

Svar

Ja, vi har to forskellige måder at sammenligne to heltal på.

Det ser ud til, at disse fakta ikke accepteres bredt i dette forum:

  1. Inde i idiomet [ ] operatørerne til aritmetisk sammenligning er -eq, -ne, -lt, -le, -gt og -ge.

    Da de også er inde i en testkommando og inde i en [[ ]].

    Ja inde i disse idiomer er =, < osv. strengoperatorer.

  2. Inde i idiomet (( )) er operatorerne til aritmetisk sammenligning == , !=, <, <=, > og >=.

    Nej, dette er ikke en “aritme etisk udvidelse “(som starter med en $) som $(( )). Det er defineret som en “sammensat kommando” i mand bash.

    Ja, den følger de samme regler (internt) for den “aritmetiske udvidelse”, men har ingen output, kun en exitværdi. Det kunne bruges sådan:

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

Hvorfor har vi to forskellige måder at sammenligne to heltal på?

Jeg antager, at sidstnævnte (( )) blev udviklet som en enklere måde at udføre aritmetiske tests på. Det er næsten det samme som $(( )) men har bare ingen output.

Hvorfor to? Nå det samme som hvorfor vi har to printf (ekstern og indbygget) eller fire test (ekstern test, indbygget test, [ og [[). Det er sådan, at skaller vokser, forbedrer et område på et år, forbedrer andre det næste år.

Hvornår skal man bruge hvilket?

Det er et meget hårdt spørgsmål, fordi der skal ikke være nogen effektiv forskel. Naturligvis er der nogle forskelle i, hvordan et [ ] arbejde og et (( )) fungerer internt, men: hvilket er bedre at sammenligne to heltal? Enhver !.

Kan disse to metoder altid bruges om hinanden, når man sammenligner to heltal?

For to tal er jeg tvunget til at sige ja.
Men for variabler, udvidelser , matematiske operationer kan der være nøgleforskelle, der skal favorisere den ene eller den anden. Jeg kan ikke sige, at absolut begge er lige. For det første kunne (( )) udføre flere matematiske operationer i rækkefølge:

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

Hvis ja, hvorfor har Bash to metoder snarere end en?

Hvis begge er nyttige, hvorfor ikke ?.

Kommentarer

  • = er en opgave, og == er en sammenligning i aritmetiske udvidelser. Spørgsmålet citerer det korrekt. Men svaret er forkert.
  • Også ( er ikke et reserveret ord i bash, så der er ikke behov for at placere mellemrum omkring ((, da i modsætning til [ eller [[

Svar

Historisk eksisterede test -kommandoen først (i det mindste så langt tilbage til Unix syvende udgave i 1979). Det brugte operatorerne = og != til at sammenligne strenge og -eq, -ne, -lt osv. For at sammenligne tal. For eksempel er test 0 = 00 falsk, men test 0 -eq 00 er sandt. Jeg ved ikke, hvorfor denne syntaks blev valgt, men det kan have været at undgå at bruge < og >, som skallen ville have parset som omdirigeringsoperatorer. test kommandoen fik en anden syntaks et par år senere: [ … ] svarer til test ….

[[ … ]] betinget syntaks, inden for hvilken < og > kan bruges som operatorer uden citat, blev tilføjet senere i ksh. Det bevarede bagudkompatibilitet med [ … ], så det brugte de samme operatorer, men tilføjede < og > for at sammenligne strenge (for eksempel [[ 9 > 10 ]] men [[ 9 -lt 10 ]]

ved hjælp af enkelt eller dobbelt beslag – bash

Aritmetiske udtryk kom også senere end test kommando, i Korn-skallen på et eller andet tidspunkt i 1980erne. De fulgte syntaksen for C-sproget, som var meget populært i Unix-kredse. Således brugte de Cs operatører: == for lighed, <= for mindre eller lige osv.

Unix Seventh Edition havde ikke aritmetiske udtryk, men den havde expr kommandoen , som også implementerede en C-lignende syntaks til heltalsoperationer, herunder dens sammenligningsoperatorer. I et shell-script skulle tegnene < og > citeres for at beskytte dem mod skallen, f.eks. if expr 1 \< 2; … svarer til if test 1 -lt 2; …. Tilføjelsen af aritmetiske udtryk til skallen gjorde mest brug af expr forældet, så det er ikke kendt i dag.

I et sh-script, du ” d bruger generelt aritmetiske udtryk til at beregne et heltal og [ … ] for at sammenligne heltal.

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

I en ksh , bash eller zsh script, kan du bruge ((…)) til begge.

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

[[ … ]] form er nyttig, hvis du vil bruge betingede forhold, der involverer andre ting end heltal.

Svar

I henhold til testman-siden, = og! = bruges til strengesammenligninger, mens udtrykkene -eq, -gt, -lt, -ge, -le og -ne er heltalssammenligninger. Jeg har altid fulgt denne konvention, når jeg skriver shell-scripts, og det fungerer altid. Vær opmærksom på, at hvis du har variabler i udtrykket, skal du muligvis citere variablerne på en eller anden måde for at undgå at foretage en nul sammenligning.

På papir foretager vi sammenligning af strenge / tal uden meget eftertanke. En computer på den anden side ved ikke, om 987 er et tal eller en række tegn. Du skal bruge de forskellige operatører til at fortælle computeren, hvad de skal gøre, så du får det rigtige resultat. Der er nogle yderligere oplysninger her , der forklarer noget af historikken. I det væsentlige er variablerne ikke-typede og har forblevet sådan for historisk kompatibilitet.

Kommentarer

  • I mit indlæg = og != er aritmetiske operatorer, mens manpage for test kun viser betingede ekspressionsoperatorer.

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *