Coding in BASH #2

30.11.2007 10:30 | blackhole_socket

Vítam vás pri pokračovaní mojho serialu článkov o programovaní v bashi. Dnes by som rád dokončil tému "Riadiace štruktúry" a pridal niečo ohladom aritmetiky v BASHi. Dúfam že sa vám budú tieto témy páčiť.

Riadiace štruktúry : pokračovanie

Štruktúra for .
Struktura for sa používa, pokial chcete počas cyklu použit rôzne hodnoty pre jednu premenú, a to tak, že pri každom priebehu cyklu bude mať premenná inú hodnotu. Napríklad chcete napísať script, ktorý desaťkrát vypíše každú sekundu plusko (+) ide to previest takto:

#!/bin/bash
echo -n "Testujem štruktúru for."
for dots in 1 2 3 4 5 6 7 8 9 10; do
  echo -n "+"
  echo "Test dokoncený."
done

Za príkazom for sa uvedie názov premennej, ktorá bude menit svou hodnotu podla hodnôt uvedených za slovom in. Blok príkazov, ktorý sa bude s takouto hodnotou prevádzať je ohraničený klúčovými slovamy do a done.
V našom prípade bude premenná x postupne nadobúdať hodnoty 1 až 10 pri
každom jednotlivom priebehu cyklu.
Tieto hodnoty však v našom cykle niesú použité (ale samozrejme použité byt môžu, a bežne sa tak aj deje).
V našom konkrétnom prípade slúžia jedine pre to, aby cyklus prebehol desatkrát. Teraz si uvedieme další príklad v ktorom už budu hodnoty v cykle použité:

#!/bin/bash
echo "Zisťuje sa existencia adresárov v systéme"
for x in /dev /etc /bin /root /var /usr /home /mnt; do
  if [ -d "$x" ]; then
    echo "Adresár $x existuje"
  else
    echo "Adresár $x neexistuje"
  fi
done

Tento príklad testuje postupne existenciu niektorích vybraních adresárov v systéme uvedeních ako hodnoty v strukture for. V príklade je skombinovaná štruktura for s štruktúrou if.
Další užitočný príklad ukáže, ako je možné pridat všetkým soúborom v aktuálnom adresári príponu php. Ukáže, že je možné použít aj žolíkové znaky pre výber souborov (v našom prípade všetky soubory, teda "*") :

#!/bin/bash
for file in *; do
  echo "Pridávam príponu .php soúboru $file..."
  mv $file $file.php
done

Žolíkové znaky tvoria obecne silnú stránku shellu a taktiež jeho používanie a programovanie značne ulahčujú a pridávajú mu velkú sílu a výkonnosť.

Štruktúra Until.
Je velmy podobná štrukture while. Jediný rozdiel je v vyhodnotování podmienky pre beh bloku kódu mezi slovamy do a done. V štrukture until sa blok kódu prevedie jedine pokial je podmienka vyhodnotená ako false (nepravda). príklad struktury:

#!/bin/bash
x=0
until [ "$x" -ge 10 ]; then
  echo "Aktuálna hodnota x je : $x"
  x=$(expr $x + 1)
  sleep 1
done

Tu je použitá štruktura until a teda príkaz test je upravený tak, aby bola štruktúra ukončená pokial bude hodnota premennej x vetšia alebo rovná 10. Znamená to, že sa vypíšu hodnoty od 0 do 9.
Príkaz sleep pozastaví beh scriptu na tolko sekúnd, kolko je uvedený parameter (v našom prípade pozastaví beh scriptu na 1 sekundu). [sleep --help]

Štruktúra Case.
Štruktura case je velmi podobná strukture if. V základe struktura case je určená pre vykonávanie jedného z niekolkích kusov kódu a to podla toho, akú hodnotu má premenná uvedená za príkazom case.
príklad struktury case:

#!/bin/bash
x=5;    # inicializuje x na hodnotu 5
# teraz se bude testovat hodnota x:
case $x in
  0) echo "Hodnota x je 0."
  ;;
  5) echo "Hodnota x je 5."
  ;;
  9) echo "Hodnota x je 9."
  ;;
  *) echo "Hodnta x nie je ani 0, ani 5, ani 9."
esac

Je vidieť, že sa vykoná príkaz, ktorý je zapísaný u hodnoty 5, ktoru premenná x má. Pokial nastane situácia, že premenná x nebude ani 0, 5 alebo 9, prevedie sa príkaz určený znakem *. Príkaz case teda vyhodnotí hodnotu riadiadiacej premennej x, podla hodnoty sa potom najde príslušná hodnota pred zátvorkou a tá sa prevedie. Ak nebude odpovedat žiadnej hodnote v strukture, skusi sa najsť *) a prevedie sa blok príkazov za ním. Ak sa nenajde hviezdička, žiadny príkaz v štrukture sa neprevedie. Celá konstrukcia by se tiež dala realizovat strukturou if:

#!/bin/bash
x=5
if [ "$x" -eq 0 ]; then
  echo "Hodnota x je 0."
elif [ "$x" -eq 5 ]; then
  echo "Hodota x je 5."
elif [ "$x" -eq 9 ]; then
  echo Hodnota x je 9.
else
  echo "Hodnota x je neurcená."
fi

Práca struktury case je podla známej struktury if rovnaká. Nakoniec ešte jeden príklad špeciálnej konštrukcie pomou case.

#!/bin/bash
echo "Je teraz ráno? Odpovedzte \"ano\" alebo \"nie\""
read timeofday
case "$timeofday" in
  ano | a | Ano | ANO )
    echo "Dobré ráno"
    ;;
  [nN]* )
    echo "Dobrý den"
    ;;
  * )
    echo "Prepácte, ale nerozumel som"
    echo "Odpovedzte \"ano\" alebo \"nie\""
    exit 1
    ;;
esac
exit 0

Pre ešte lepšiu kontrolu odpovede ano môžeme využit konštrukciu pomocou žolíkových znakov.

[aA] | [aA][nN][oO] )

Aritmetika

BASH takisto ako vetšina programovacích jazykov dokáže prevádzať matematické výrazy.
Aritmetika sa prevádza pomocou príkazu expr. Rovnako ako príkaz true je aj príkaz expr pomalí, a preto sa može aritmetika prevádzať pomocou interných príkazov bash. Rovnako ako je dvojbodka alternativa k príkazu true, je ku príkazu expr alternativa. A tou je uzavretie výrazu do gulatých zátvoriek. Výsledok dostaneme pomocou konštrukcie $((...)). Rozdiel oproti výrazu $(...) je v počte zátvoriek.

Naseldujúci príklad slúžy na sčítanie čísliel :

#!/bin/bash
x=8
y=4
z=$(($x + $y))
echo "Sucet $x a $y je $z"

tabulka mat. operácií v bashi :

Operácia      Znak
Scítanie         +
Odcítanie          -
Násobenie     *
Delenie     /
Delenie modulo %

Delenie modulo je zbytok po delení. Napríklad 5 % 2 = 1, pretože 5 deleno 2 je 2, zbytok 1. Bash dokáže pracovať jedine s celými číslami !
príklad scriptu s aritmetickými operaciami:

#!/bin/bash
x=5
y=3
add=$(($x + $y))
sub=$(($x - $y))
mul=$(($x * $y))
div=$(($x / $y))
mod=$(($x % $y))
echo "Sucet: $add"
echo "Rozdiel: $sub"
echo "Sucin: $mul"
echo "Podiel: $div"
echo "Zbytok: $mod"

Namiesto add=$(($x + $y)) je taktiež možné použiť add=$(expr $x + $y) alebo add=`expr $x + $y`.
Odporúčam [ expr --help ].
-------------------------------------------------------------------------------------------------------------------------
Nabudúce sa pozrieme na hlavne na uvodzovky a ostatné "exkluzivity" BASHu .
Tento článok vznikol vdaka niekoľkým zdrojom.

    • Re: Coding in BASH #2 30.11.2007 | 16:36
      Avatar mysho   Používateľ

      kolko ti trvalo kym si to vsetko napisal?

      ===== google
      • Re: Coding in BASH #2 30.11.2007 | 17:14
        Avatar y   Používateľ

        preco je tato otazka pre teba podstatna? je tam kus citit nejaku nevyslovenu kritiku (aspon mne to tak znie) a to nie je moc dobre...(samozrejme, to, ze je nevyslovena, nie to, ze kritika)
        ==
        program je nastroj na dosiahnutie ciela, nie ciel samotny.

        == Don't buy drugs...Become a pop star and get them for free!
        • Re: Coding in BASH #2 05.12.2007 | 21:42
          Avatar mysho   Používateľ

          ani nie taka podstatna ale ma to zaujima. nevyslovena kritika? v ziadnom pripade. nehladaj tam to co tam nie je. nemam mu co vytykat.

          ===== google
          • Re: Coding in BASH #2 05.12.2007 | 23:00
            Avatar y   Používateľ

            ok, len to tak velmi cudne znelo :-)
            ==
            Don't buy drugs...Become a pop star and get them for free!

            == Don't buy drugs...Become a pop star and get them for free!
      • Re: Coding in BASH #2 30.11.2007 | 17:47
        Avatar blackhole_socket   Používateľ

        ani neviem ... ale takéto otázky by si mohol riešiť cez pm ...pokial nemáš čo dodať
        _______________________________________________________
        Linux je ako okena,kvalitný a lacný čistič oken...

    • Re: Coding in BASH #2 30.11.2007 | 17:48
      Avatar stanojr   Používateľ

      ja pouzivam prikaz seq v bashi ked potrebujem v premennej menit cisla v cykle, napr.
      namiesto:
      for dots in 1 2 3 4 5 6 7 8 9 10; do
      napisem
      for dots in `seq 1 10`; do

      da sa to pouzit pekne na tahanie holych tiet z galerii
      napr.

      for x in `seq 1 16`; do
      wget http://url/$x.jpg
      done

      :))

      • Re: Coding in BASH #2 30.11.2007 | 18:23
        Avatar blackhole   Návštevník

        scriptik na tento ucel som mal uz davno v plane napisat len som sa k tomu nedostal a ani ku kodeniu v bashi. da sa to pouzit nie len na tety...
        pripomenul si mi jednu z mnohych veci, ktorym sa chcem pozriet na zubky, len na nich nemam cas :(

        mimochodom socket, potesil ma tento serial. nechcelo sa mi zhanat nieco podobne tak som sa na to stale vykaslal a teraz to je pekne pod nosom.

      • Re: Coding in BASH #2 04.12.2007 | 23:25
        Avatar marvin   Používateľ

        to zalezi od os. seq nie je standardny unix nastroj,napr vo freebsd nie je (co je imho skoda).
        ------
        IP on everything!:)

        ------ Kto je Španielsko?Prečo je Hitler?Kedy je vľavo?