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
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:
-
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. -
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, ==
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 fortest
kun viser betingede ekspressionsoperatorer.
= != < <= > >=
sammenlign strenge .1 -eq 01
men1 != 01
og8 -lt 42
men8 > 42