Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Aritmetická expanze

Výraz

$(( term ))

se expanduje na výsledek vyhodnocení aritmetického výrazu term. Na rozdíl od expr a od tvaru $[ … ] použitého v kapitole Aritmetika jde o vestavěnou konstrukci, která nespouští žádný další proces. Tvar $(( … )) je dnes doporučovaný; $[ … ] je zastaralý a v nových skriptech se mu vyhýbáme,1 i když jej ve starším kódu potkáme. Uvnitř výrazu jsou povoleny mezery.

> echo $(( 2 + 3 ))
5
> echo $(( 10 / 3 ))
3
> echo $(( 10 % 3 ))
1

Proměnné uvnitř

Uvnitř $(( )) se na jména proměnných dívá shell jako na proměnné i bez $. Obě následující varianty jsou tedy správné, druhá je čitelnější.

var1=10
var2=20

vysledek=$(( ${var1} * ${var2} ))
vysledek=$(( var1 * var2 ))

Prázdná nebo nenastavená proměnná se vyhodnotí jako 0. To je pohodlné, ale snadno to zamaskuje překlep ve jméně proměnné.

> echo $(( NEEXISTUJE + 5 ))
5

Operátory

K dispozici jsou operátory známé z jazyka C, včetně priority a závorek:

  • aritmetické + - * / % ** (mocnina)
  • porovnání < <= > >= == !=
  • logické && || !
  • bitové & | ^ ~ << >>
  • přiřazovací = += -= *= /= %=
  • inkrement a dekrement ++ --
  • ternární operátor podmínka ? a : b
> echo $(( 2 ** 10 ))
1024
> echo $(( 1 << 8 ))
256
> x=5
> echo $(( x > 3 ? 100 : 200 ))
100

Porovnání vrací 1 pro pravdu a 0 pro nepravdu. Pozor, je to opačně než u návratových hodnot příkazů (viz Návratové hodnoty).

Aritmetika jako příkaz

Kromě expanze existuje i tvar (( term )), který je příkazem. Výraz se vyhodnotí a příkaz skončí s návratovou hodnotou 0, je-li výsledek nenulový, a s hodnotou 1, je-li výsledek nula. To je právě obrácení zmíněné výše, které umožňuje psát podmínky přirozeně.

if (( pocet > 10 ))
then
    echo "vice nez deset"
fi

# pocitadlo v cyklu
i=0
while (( i < 5 ))
do
    echo ${i}
    (( i++ ))
done

Ve srovnání s [ "${a}" -gt "${b}" ] je tento zápis čitelnější a nemusíme řešit uvozovky, protože uvnitř (( )) neprobíhá dělení slov. Jde ovšem o rozšíření Bashe, které v jiných shellech nemusí být k dispozici (viz Větvení).

Konstrukce (( )) se objevuje také v hlavičce céčkového cyklu for, který jsme viděli v kapitole Cykly:

for (( i=1; i <= 10; i++ ))
do
    echo ${i}
done

Číselné soustavy

Číslo začínající nulou je považováno za osmičkové, číslo začínající 0x za šestnáctkové. Obecně lze soustavu zapsat jako zaklad#cislo.

> echo $(( 010 ))
8
> echo $(( 0xff ))
255
> echo $(( 2#1010 ))
10

Osmičková interpretace je zdrojem chyb při práci s daty, která používají nuly zleva — třeba s měsíci nebo dny v datu.

> MESIC=09
> echo $(( MESIC + 1 ))
bash: 09: value too great for base (error token is "09")

Řešením je vynutit desítkovou soustavu zápisem 10#:

> echo $(( 10#${MESIC} + 1 ))
10

Aritmetika je celočíselná

Stejně jako u expr platí, že $(( )) počítá pouze s celými čísly a dělení ořezává. Pro výpočty s desetinnými čísly je nutné použít bc, jak je popsáno v kapitole Aritmetika.


  1. $[ … ] je v dokumentaci Bashe uveden jako zastaralý a v budoucích verzích může zmizet. V ukázkách ve zbytku textu se ještě vyskytuje. ↩