V jazyce Bash lze porovnat dvě celá čísla pomocí podmíněného výrazu
arg1 OP arg2
OP je jeden z
-eq
,-ne
,-lt
,-le
,-gt
nebo-ge
. Tyto aritmetické binární operátory vrátí true, pokud arg1 je rovno, ne rovno, menší než, menší než nebo rovno, větší než nebo větší než nebo rovno arg2 , resp. Arg1 a arg2 mohou být kladná nebo záporná celá čísla.
nebo aritmetický výraz:
<= >= < >
srovnání
== !=
rovnost a nerovnost
Proč máme dva různé způsoby porovnání dvou celých čísel? Kdy použít které?
Například [[ 3 -lt 2 ]]
používá podmíněný výraz a (( 3 < 2 ))
aritmetický výraz. Oba vrátí 0, když je srovnání pravdivé.
Lze tyto dvě metody při porovnávání dvou celých čísel vždy použít zaměnitelně? Pokud ano, proč má Bash spíše dvě metody než jednu?
Komentáře
Odpověď
Ano, máme dva různé způsoby porovnání dvou celých čísel.
Zdá se, že tato fakta nejsou na tomto fóru široce přijímána:
-
Uvnitř idiomu
[ ]
jsou operátory aritmetického srovnání-eq
,-ne
,-lt
,-le
,-gt
a-ge
.Protože jsou také uvnitř testovacího příkazu a uvnitř
[[ ]]
.Ano, uvnitř těchto idiomů jsou
=
,<
atd. operátory řetězců. -
Uvnitř idiomu
(( ))
jsou operátory pro aritmetické srovnání==
,!=
,<
,<=
,>
a>=
.Ne, nejde o aritmus etická expanze „(která začíná
$
) jako$(( ))
. Je definován jako „složený příkaz“ v bash člověka.Ano, řídí se stejnými pravidly (interně) „aritmetické expanze“, ale nemá žádný výstup, pouze výstupní hodnotu. Mohlo by to být použito takto:
if (( 2 > 1 )); then ...
Proč máme dva různé způsoby porovnání dvou celých čísel?
Myslím, že druhá (( ))
byla vyvinuta jako jednodušší způsob provádění aritmetických testů. Je téměř stejný jako $(( ))
, ale nemá žádný výstup.
Proč dva? Stejně jako důvod, proč máme dva printf
(externí a vestavěné) nebo čtyři testy (externí test
, vestavěné test
, [
a [[
). To je způsob, jakým skořápky rostou, vylepšují některé oblasti za jeden rok a vylepšují některé další v příštím roce.
Kdy použít který?
To je velmi těžká otázka, protože neměl by existovat žádný efektivní rozdíl. Samozřejmě existují určité rozdíly ve způsobu, jakým interně fungují práce [ ]
a práce (( ))
, ale: což je lepší porovnat dvě celá čísla? Kdokoli !.
Při porovnávání dvou celých čísel, lze tyto dvě metody vždy použít zaměnitelně?
U dvou čísel jsem nucen říct ano.
Ale u proměnných, rozšíření Matematické operace mohou existovat klíčové rozdíly, které by měly upřednostňovat jednu nebo druhou. Nemohu říci, že absolutně jsou si oba rovni. Za prvé, (( ))
může provádět několik matematických operací za sebou:
if (( a=1, b=2, c=a+b*b )); then echo "$c"; fi
Pokud ano, proč má Bash dvě metody spíše než jedna?
Pokud jsou obě užitečné, proč ne ?.
Komentáře
-
=
je úkol a==
srovnání aritmetických rozšíření. Otázka to cituje správně. Ale odpověď je špatná. - Také
(
není v bash vyhrazené slovo, takže není třeba přidávat mezery kolem((
, as na rozdíl od[
nebo[[
odpovědi
Historicky test
příkaz existoval jako první (přinejmenším již od Unix sedmé vydání v roce 1979). Pomocí operátorů =
a !=
porovnal řetězce a -eq
, -ne
, -lt
atd. Pro porovnání čísel. Například test 0 = 00
je nepravdivý, ale test 0 -eq 00
je pravdivý. Nevím, proč byla zvolena tato syntaxe, ale bylo možné, že jsem se vyhnul použití <
a >
, které by shell měl analyzováno jako operátoři přesměrování. Příkaz test
získal o několik let později další syntaxi: [ … ]
je ekvivalentní test …
.
[[ … ]]
podmíněná syntaxe, uvnitř které <
a >
lze použít jako operátory bez uvozovek, bylo přidáno později, v ksh. Zachovalo si zpětnou kompatibilitu s [ … ]
, takže používalo stejné operátory, ale přidalo <
a >
k porovnání řetězců (například [[ 9 > 10 ]]
ale [[ 9 -lt 10 ]]
). Další informace najdete v použití jednoduché nebo dvojité závorky – bash
Aritmetické výrazy také přišly později než test
příkaz,
v prostředí Korn , někdy v 80. letech. Řídili se syntaxí jazyka C, která byla v unixových kruzích velmi populární. Proto použili operátory C:==
pro rovnost,<=
pro menší nebo rovné atd.
Sedmé vydání Unixu nemělo aritmetické výrazy, ale mělo expr
příkaz , který také implementoval Syntaxe typu C pro celočíselné operace, včetně operátorů porovnání. Ve skriptu prostředí musely být znaky <
a >
citovány, aby byly chráněny před shellem, např. if expr 1 \< 2; …
je ekvivalentní s if test 1 -lt 2; …
. Přidání aritmetických výrazů do shellu nejvíce využívalo expr
zastaralé, takže dnes již není dobře známé.
Ve skriptu sh d obecně používá aritmetické výrazy k výpočtu celočíselné hodnoty a [ … ]
k porovnání celých čísel.
if [ "$((x + y))" -lt "$z" ]; then …
V ksh , skript bash nebo zsh, můžete použít ((…))
pro oba.
if ((x + y < z)); then …
[[ … ]]
formulář je užitečný, pokud chcete použít podmíněné výrazy zahrnující i jiné věci než celá čísla.
Odpověď
Podle stránka test man, = a! = se používají pro porovnání řetězců, zatímco výrazy -eq, -gt, -lt, -ge, -le a -ne jsou celočíselná srovnání. Tuto konvenci jsem vždy dodržoval při psaní shell skriptů a vždy to funguje. Uvědomte si, že pokud máte ve výrazu proměnné, možná budete muset nějakým způsobem proměnné citovat, abyste se vyhnuli nulovému porovnání.
Na papíře provádíme srovnání řetězců a čísel bez velkého přemýšlení. Počítač na druhé straně neví, jestli je 987 číslo nebo řetězec znaků. Potřebujete různé operátory, aby řekli počítači, co má dělat, abyste dosáhli správného výsledku. zde jsou některé další informace, které vysvětlují část historie. Proměnné jsou v zásadě netypové a zůstaly tak pro historickou kompatibilitu.
Komentáře
- V mém příspěvku
=
a!=
jsou aritmetické operátory, zatímco stránkatest
zobrazuje pouze operátory podmíněného výrazu.
= != < <= > >=
porovnat řetězce .1 -eq 01
ale1 != 01
a8 -lt 42
ale8 > 42