Az expr, $ (()), (())

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

Válasz

  1. Aritmetika esetében az expr archaikus. Ne használja. *

  2. $((...)) é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 a echo 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 
  3. Ha lebegést szeretne pontszámításokhoz használja a bc vagy a awk:

    $ 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ása case STRING in PATTERN). Az expr 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ása case STRING in PATTERN) néven írható. Az expr 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ő.

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük