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
- Zobrazit také unix.stackexchange.com/questions/149823/…
Odpověď
-
Pro aritmetiku je
exprarchaický. Nepoužívejte to. * -
$((...))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ý veechoprohláš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 -
Pokud chcete plovoucí bodové výpočty, použijte
bcneboawk:$ 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
spromě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 : REGEXlze napsat jakocase STRING in PATTERN).exprje 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 : REGEXlze zapsat jakocase STRING in PATTERN).exprje 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ě.