parancsértelmezőben a expr $a*$b
$(($a+$b))
.
De miért ne csak a (($a+$b))
használatával, mert minden erőforrásban azt írják, hogy a (())
egész számításra szolgál.
Tehát akkor használjuk az $(())
-t, ha változók vannak egész számok helyett? És mit használjunk az $(())
helyett, amikor a változók lebegő értékeket képesek fogadni?
Megjegyzések
- Lásd még unix.stackexchange.com/questions/149823/…
Válasz
-
Aritmetika esetében az
expr
archaikus. Ne használja. * -
$((...))
és((...))
nagyon hasonlóak. Mindkettő csak egész számításokat végez. A különbség az, hogy$((...))
visszaadja a számítás eredményét, a((...))
nem. Így hasznos aecho
utasításokban:$ a=2; b=3; echo $((a*b)) 6
((...))
akkor hasznos, ha változót akar rendelni, vagy kilépési kódot szeretne beállítani:$ a=3; b=3; ((a==b)) && echo yes yes
-
Ha lebegést szeretne pontszámításokhoz használja a
bc
vagy aawk
:$ echo "4.7/3.14" | bc -l 1.49681528662420382165 $ awk "BEGIN{print 4.7/3.14}" 1.49682
* Félretéve a expr
továbbra is hasznos marad a karakterlánc-kezelésnél, ha a globusok nem elég jók, és a reguláris kifejezések kezeléséhez POSIX-módszerre van szükség.
Megjegyzések
- Ha az expr archaikus, akkor mit használjunk az expr szöveg helyett: '. * '
- Ha
s
egy shell változó, akkor annak hossza${#s}
- A $ {#} számos argumentumot jelent, a $ (# s} pedig azt, hogy a változó számos karakterét csinálja?
- Igen. Ez ' igaz.
- @Stranger Az
expr STRING : REGEX
sok felhasználásacase STRING in PATTERN)
. Azexpr
csak akkor hasznos, ha a REGEX ' nem fejezhető ki shell helyettesítő karakterekkel.
Válasz
Az expr régi, de csak korlátozottan használható, gondolhatom. Mondja, hogy keresni szeretne egy karakterláncot. Ha POSIX-ban akarsz maradni a grep segítségével, akkor pipát kell használnod:
if echo november | grep nov then : do something fi
Az expr ezt pipa nélkül is megteheti:
if expr november : nov then : do something fi
az egyetlen fogás, hogy az expr lehorgonyzott karakterláncokkal működik, ezért ha az elejét követően szeretne egyeztetni, módosítania kell a REGEXP-t:
if expr november : ".*ber" then : do something fi
A (( ))
tekintetében ez a konstrukció nem POSIX , ezért kerülni kell.
A $(( ))
vonatkozásában nem kell feltüntetnie a dollárjelet:
$ fo=1 $ go=2 $ echo $((fo + go)) 3
megjegyzések
- Az
expr STRING : REGEX
sok felhasználásacase STRING in PATTERN)
néven írható. Azexpr
csak akkor hasznos, ha a REGEX ' nem fejezhető ki shell helyettesítő karakterekkel.
Válasz
Úgy tűnik, hogy a következő programok nagyjából ugyanazt csinálják, és valójában nem is különböznek egymástól. De ez nem igaz.
#!/bin/bash s=-1000 for (( i=0; i<1000000; i++ )), do s=$((s+1)) echo $s
Ez a helyes módszer ennek megvalósítására. Az s + 1 kifejezést a shell értékeli, és hozzárendelhető egy változóhoz.
#!/bin/bash s=-1000 for (( i=0; i<1000000; i++ )), do s=`expr $s+1` echo $s
Itt a kifejezést az expr program fogja kiszámítani, amely nem a beépített shell, hanem egy külső Unix program. Tehát ahelyett, hogy egyszerűen hozzáadnánk 1-et és s-t, egy programot el kell indítani, és a kimenetét el kell olvasni és be kell írni a változóba. A program elindításához sok erőforrásra és sok időre van szükség. És ezt a programot 1000000-szor futtatják. Tehát a program sokkal lassabb lesz, mint az előző. Ennek ellenére a kód megfelelően működik.
#!/bin/bash -e s=-1000 for (( i=0; i<1000000; i++ )), do ((s=s+1)) echo $s
Ha az -e jelző nincs beállítva, akkor a program is megfelelően fog működni. De ha az -e beállítva, amikor s = -1 és ((s = s + 1)) kiszámításra kerül. Az s = s + 1 kifejezés értéke 0, és a ((0)) kilépési kódja> 0, amelyet hibaként értelmez a shell, és a shell kilép a programból.
Az -e jelző beállításának oka az, hogy ez a hiba feldolgozásának legegyszerűbb módja: állítsa le, ha hiba fordul elő.