In shell-script kunnen we expr $a*$b vervangen door $(($a+$b)). 
 Maar waarom niet alleen met (($a+$b)), want in elke bron staat geschreven dat (()) bedoeld is voor de berekening van gehele getallen. 
 Dus we gebruiken $(()) als er variabelen zijn in plaats van gehele getallen, nietwaar? En wat moeten we gebruiken in plaats van $(()) wanneer variabelen zwevende waarden kunnen ontvangen? 
Opmerkingen
- Zie ook unix.stackexchange.com/questions/149823/…
Antwoord
- 
Voor rekenkunde is exprarchaïsch. Gebruik het niet. *
- 
$((...))en((...))lijken erg op elkaar. Beide doen alleen berekeningen met gehele getallen. Het verschil is dat$((...))het resultaat van de berekening retourneert en((...))niet. Dus$((...))is handig inechostatements:$ a=2; b=3; echo $((a*b)) 6((...))is handig als u een variabele wilt toewijzen of een afsluitcode wilt instellen:$ a=3; b=3; ((a==b)) && echo yes yes
- 
Als u zwevend wilt puntberekeningen, gebruik bcofawk:$ echo "4.7/3.14" | bc -l 1.49681528662420382165 $ awk "BEGIN{print 4.7/3.14}" 1.49682
 * Even terzijde: expr blijft handig voor het afhandelen van tekenreeksen wanneer klodders niet goed genoeg zijn en een POSIX-methode nodig is om reguliere expressies af te handelen. 
Opmerkingen
- Als expr archaïsch is, wat moeten we dan gebruiken in plaats van expr-tekst: '. * '
-  Als seen shellvariabele is, is de lengte${#s}
- $ {#} betekent een aantal argumenten en $ (# s} betekent een aantal karakters van een variabele?
- Ja. Dat ' klopt.
-  @Stranger Veel gebruik van expr STRING : REGEXkan worden geschreven alscase STRING in PATTERN).expris alleen nuttig als REGEX ' niet kan worden uitgedrukt met shell-jokertekens.
Answer
expr is oud, maar het heeft een beperkt nut dat ik kan bedenken. Stel dat u in een string wilt zoeken. Als je POSIX met grep wilt blijven, moet je een pipe gebruiken:
if echo november | grep nov then : do something fi expr kan dit doen zonder een pipe:
if expr november : nov then : do something fi de enige catch is expr werkt met verankerde strings, dus als je wilt matchen na het begin, moet je de REGEXP wijzigen:
if expr november : ".*ber" then : do something fi  Met betrekking tot (( )), deze constructie  is niet POSIX , dus moet worden vermeden. 
 Met betrekking tot $(( )) hoeft u het dollarteken niet op te nemen: 
$ fo=1 $ go=2 $ echo $((fo + go)) 3 Opmerkingen
-  Veel gebruik van expr STRING : REGEXkan worden geschreven alscase STRING in PATTERN).expris alleen nuttig als REGEX ' niet kan worden uitgedrukt met shell-jokertekens.
Answer
Het lijkt erop dat de volgende programmas min of meer hetzelfde doen en niet echt verschillen. Maar dat is niet waar.
#!/bin/bash s=-1000 for (( i=0; i<1000000; i++ )), do s=$((s+1)) echo $s Dit is de juiste manier om dit te implementeren. De uitdrukking s + 1 wordt geëvalueerd door de shell en kan worden toegewezen aan een variabele.
#!/bin/bash s=-1000 for (( i=0; i<1000000; i++ )), do s=`expr $s+1` echo $s Hier zal de uitdrukking worden berekend door het programma expr, dat” geen shell is ingebouwd, maar een extern Unix-programma. Dus in plaats van simpelweg 1 en s toe te voegen, moet een programma worden gestart en moet de uitvoer ervan worden gelezen en naar de variabele worden geschreven. Het starten van een programma vergt veel middelen en veel tijd. En dit programma wordt 1000000 keer uitgevoerd. Het programma zal dus veel langzamer zijn dan het vorige. Desalniettemin werkt de code correct.
#!/bin/bash -e s=-1000 for (( i=0; i<1000000; i++ )), do ((s=s+1)) echo $s Als de vlag -e niet is ingesteld, zal het programma ook correct werken. Maar als -e is ingesteld wanneer s = -1 en ((s = s + 1)) wordt berekend. De uitdrukking s = s + 1 resulteert in 0 en de afsluitcode van ((0)) is> 0, wat door de shell wordt geïnterpreteerd als een fout en de shell verlaat het programma.
De reden om de vlag -e in te stellen is dat dit de eenvoudigste manier is om fouten te verwerken: stop als er een fout optreedt.