In Bash kunnen twee gehele getallen worden vergeleken met voorwaardelijke uitdrukking
arg1 OP arg2
OP is een van
-eq
,-ne
,-lt
,-le
,-gt
, of-ge
. Deze rekenkundige binaire operatoren retourneren waar als arg1 gelijk is aan, niet gelijk aan, kleiner dan, kleiner dan of gelijk aan, groter dan of groter dan of gelijk aan arg2 , respectievelijk. Arg1 en arg2 kunnen positieve of negatieve gehele getallen zijn.
of rekenkundige uitdrukking:
<= >= < >
vergelijking
== !=
gelijkheid en ongelijkheid
Waarom hebben we twee verschillende manieren om twee gehele getallen te vergelijken? Wanneer welke te gebruiken?
[[ 3 -lt 2 ]]
gebruikt bijvoorbeeld voorwaardelijke expressie en (( 3 < 2 ))
gebruikt rekenkundige expressie. Beide geven 0 terug als de vergelijking waar is.
Kunnen deze twee methoden altijd door elkaar worden gebruikt bij het vergelijken van twee gehele getallen? Zo ja, waarom heeft Bash twee methoden in plaats van één?
Reacties
Antwoord
Ja, we hebben twee verschillende manieren om twee gehele getallen te vergelijken.
Het lijkt erop dat deze feiten niet algemeen worden geaccepteerd in dit forum:
-
Binnen het idioom
[ ]
zijn de operatoren voor rekenkundige vergelijking-eq
,-ne
,-lt
,-le
,-gt
en-ge
.Omdat ze ook binnen een testopdracht en in een
[[ ]]
.Ja binnen deze idiomen,
=
,<
, enz. Zijn stringoperatoren. -
Binnen het idioom
(( ))
zijn de operatoren voor rekenkundige vergelijking==
,!=
,<
,<=
,>
, en>=
.Nee, dit is geen “Arithm etische uitbreiding “(die begint met een
$
) als$(( ))
. Het wordt gedefinieerd als een “Samengesteld commando” in man bash.Ja, het volgt dezelfde regels (intern) van de “Rekenkundige uitbreiding” maar heeft geen output, alleen een exit-waarde. Het zou als volgt kunnen worden gebruikt:
if (( 2 > 1 )); then ...
Waarom hebben we twee verschillende manieren om twee gehele getallen te vergelijken?
Ik vermoed dat de laatste (( ))
is ontwikkeld als een eenvoudigere manier om rekenkundige tests uit te voeren. Het is bijna hetzelfde als de $(( ))
maar heeft gewoon geen output.
Waarom twee? Hetzelfde als waarom we twee printf
(extern en ingebouwd) of vier tests (extern test
, ingebouwd test
, [
en [[
). Dat is de manier waarop de schelpen groeien, een bepaald gebied in het ene jaar verbeteren, het andere het volgende jaar verbeteren.
Wanneer welke te gebruiken?
Dat is een zeer moeilijke vraag, want er mag geen effectief verschil zijn. Natuurlijk zijn er enkele verschillen in de manier waarop een [ ]
werkt en een (( ))
intern werkt, maar: wat is beter om twee gehele getallen te vergelijken? Elk één !.
Kunnen deze twee methoden altijd door elkaar worden gebruikt als je twee gehele getallen vergelijkt?
Voor twee getallen moet ik ja zeggen.
Maar voor variabelen, uitbreidingen , wiskundige bewerkingen kunnen er belangrijke verschillen zijn die de ene of de andere begunstigen. Ik kan niet zeggen dat absoluut beide gelijk zijn. Ten eerste kan de (( ))
verschillende wiskundige bewerkingen achter elkaar uitvoeren:
if (( a=1, b=2, c=a+b*b )); then echo "$c"; fi
Zo ja, waarom heeft Bash twee methoden in plaats van één?
Als beide nuttig zijn, waarom niet ?.
Reacties
-
=
is een toewijzing en==
is een vergelijking in rekenkundige uitbreidingen. De vraag citeert het correct. Maar het antwoord is fout. - Ook
(
is geen gereserveerd woord in bash, dus het is niet nodig om spaties rond((
te plaatsen, aangezien in tegenstelling tot[
of[[
Antwoord
Historisch gezien bestond het test
-commando als eerste (tenminste even ver terug naar Unix Seventh Edition in 1979). Het gebruikte de operatoren =
en !=
om strings te vergelijken, en -eq
, -ne
, -lt
, etc. om getallen te vergelijken. test 0 = 00
is bijvoorbeeld onwaar, maar test 0 -eq 00
is waar. Ik weet niet waarom deze syntaxis is gekozen, maar het kan zijn geweest om <
en >
te vermijden, wat de shell zou hebben geparseerd als omleidingsoperatoren. Het test
commando kreeg een paar jaar later een andere syntaxis: [ … ]
is gelijk aan test …
.
De [[ … ]]
voorwaardelijke syntaxis, waarin <
en >
kan worden gebruikt als operatoren zonder aanhalingstekens, werd later toegevoegd, in ksh. Het behield achterwaartse compatibiliteit met [ … ]
, dus het gebruikte dezelfde operatoren, maar voegde <
en >
om strings te vergelijken (bijvoorbeeld [[ 9 > 10 ]]
maar [[ 9 -lt 10 ]]
). Voor meer informatie, zie met enkele of dubbele haakjes – bash
Rekenkundige uitdrukkingen kwamen ook later dan de test
commando,
in de Korn-shell , ergens in de jaren tachtig. Ze volgden de syntaxis van de C-taal, die erg populair was in Unix-kringen. Daarom gebruikten ze de operatoren van C:==
voor gelijkheid,<=
voor minder-of-gelijk, enz.
Unix Seventh Edition had geen “rekenkundige uitdrukkingen”, maar wel het expr
commando , dat ook een C-achtige syntaxis voor bewerkingen met gehele getallen, inclusief de vergelijkingsoperatoren. In een shellscript moesten de tekens <
en >
worden geciteerd om ze tegen de shell te beschermen, bijv. if expr 1 \< 2; …
is gelijk aan if test 1 -lt 2; …
. De toevoeging van rekenkundige uitdrukkingen aan de shell maakte het meeste gebruik van expr
verouderd, dus het is “niet zo bekend vandaag.
In een sh-script, jij” d gebruiken over het algemeen rekenkundige uitdrukkingen om een geheel getal te berekenen, en [ … ]
om gehele getallen te vergelijken.
if [ "$((x + y))" -lt "$z" ]; then …
In een ksh , bash of zsh script, kunt u ((…))
voor beide gebruiken.
if ((x + y < z)); then …
Het [[ … ]]
formulier is handig als u voorwaarden wilt gebruiken die andere dingen dan gehele getallen omvatten.
Antwoord
Volgens de test man-pagina, = en! = worden gebruikt voor stringvergelijkingen, terwijl de uitdrukkingen -eq, -gt, -lt, -ge, -le en -ne integer-vergelijkingen zijn. Ik heb deze conventie altijd gevolgd bij het schrijven van shell-scripts en het werkt altijd. Houd er rekening mee dat als je variabelen in de uitdrukking hebt, je de variabelen op de een of andere manier moet citeren om een nulvergelijking te voorkomen.
Op papier vergelijken we zonder veel nadenken tekenreeksen / getallen, een computer daarentegen weet niet of 987 een getal of een reeks tekens is. Je hebt de verschillende operators nodig om de computer te vertellen wat hij moet doen, zodat je het juiste resultaat krijgt. Er is hier wat aanvullende informatie die een deel van de geschiedenis verklaart. In wezen zijn de variabelen niet getypeerd en zijn ze zo gebleven voor historische compatibiliteit.
Opmerkingen
- In mijn bericht
=
en!=
zijn rekenkundige operatoren, terwijl de manpage vantest
alleen voorwaardelijke expressie-operatoren toont.
= != < <= > >=
vergelijk strings .1 -eq 01
maar1 != 01
en8 -lt 42
maar8 > 42