Pomocí expr, $ (()), (())

Ve skriptu prostředí můžeme nahradit expr $a*$b $(($a+$b)).

Ale proč ne nejen s (($a+$b)), protože v každém zdroji je napsáno, že (()) je pro celočíselný výpočet.

Takže $(()) používáme, když místo celočíselných hodnot existují proměnné, že? A co bychom měli použít místo $(()), když proměnné mohou přijímat plovoucí hodnoty?

Komentáře

Odpověď

  1. Pro aritmetiku je expr archaický. Nepoužívejte to. *

  2. $((...)) a ((...)) jsou si velmi podobné. Oba provádějí pouze celočíselné výpočty. Rozdíl je v tom, že $((...)) vrací výsledek výpočtu a ((...)) nikoli. Tedy $((...)) je užitečný ve echo prohlášeních:

    $ a=2; b=3; echo $((a*b)) 6 

    ((...)) je užitečné, když chcete přiřadit proměnnou nebo nastavit výstupní kód:

    $ a=3; b=3; ((a==b)) && echo yes yes 
  3. Pokud chcete plovoucí bodové výpočty, použijte bc nebo awk:

    $ echo "4.7/3.14" | bc -l 1.49681528662420382165 $ awk "BEGIN{print 4.7/3.14}" 1.49682 

* Kromě toho expr zůstává užitečný pro zpracování řetězců, když globy nejsou dost dobré a pro zpracování regulárních výrazů je nutná metoda POSIX.

Komentáře

  • Pokud je expr archaický, co bychom měli použít místo expr textu: '. * '
  • Pokud je s proměnná prostředí, její délka je ${#s}
  • $ {#} znamená počet argumentů a $ (# s} znamená počet znaků proměnné, že?
  • Ano. To ' má pravdu.
  • @Stranger Mnoho použití expr STRING : REGEX lze napsat jako case STRING in PATTERN). expr je užitečný, pouze pokud REGEX nelze ' vyjádřit zástupnými znaky prostředí.

Odpověď

expr je starý, ale má jedno omezené použití, na které si myslím. Řekněme, že chcete vyhledat řetězec. Pokud chcete zůstat POSIX s grep, musíte použít rouru:

if echo november | grep nov then : do something fi 

expr to dokáže bez roury:

if expr november : nov then : do something fi 

jediným úlovkem je expr pracuje s ukotvenými řetězci, takže pokud se chcete shodovat po začátku, musíte změnit REGEXP:

if expr november : ".*ber" then : do something fi 

Pokud jde o (( )), tento konstrukt není POSIX , takže je třeba se mu vyhnout.

Pokud jde o $(( )), nemusíte uvádět znak dolaru:

$ fo=1 $ go=2 $ echo $((fo + go)) 3 

Komentáře

  • Mnoho použití expr STRING : REGEX lze zapsat jako case STRING in PATTERN). expr je užitečný, pouze pokud REGEX nelze ' vyjádřit zástupnými znaky prostředí.

Odpověď

Zdá se, že následující programy jsou víceméně stejné a ve skutečnosti se neliší. Ale to není pravda.

#!/bin/bash s=-1000 for (( i=0; i<1000000; i++ )), do s=$((s+1)) echo $s 

Toto je správný způsob implementace. Výraz s + 1 je vyhodnocen shellem a lze jej přiřadit k proměnné.

#!/bin/bash s=-1000 for (( i=0; i<1000000; i++ )), do s=`expr $s+1` echo $s 

Zde bude výraz vypočítán programem expr, který není zabudován do shellu, ale je externím unixovým programem. Takže místo jednoduchého přidání 1 a s musí být spuštěn program a jeho výstup musí být přečten a zapsán do proměnné. Spuštění programu vyžaduje spoustu zdrojů a spoustu času. A tento program je spuštěn 10 000 000krát. Program tedy bude mnohem pomalejší než předchozí. Kód přesto funguje správně.

#!/bin/bash -e s=-1000 for (( i=0; i<1000000; i++ )), do ((s=s+1)) echo $s 

Pokud není nastaven příznak -e, bude program fungovat také správně. Pokud je však -e nastaveno, když s = -1 a ((s = s + 1)). Vypočítá se výraz s = s + 1 na hodnotu 0 a kód ukončení ((0)) je> 0, což shell interpretuje jako chybu a shell ukončí program.

Důvodem pro nastavení parametru -e je, že se jedná o nejjednodušší způsob zpracování chyb: zastavit, pokud dojde k chybě.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *