Ci

Ciklusok ebben a kurzusban: Bash

{one: "1 feladat", other: "%{count} feladat"}

A(z) Ciklusok fogalomról

A Bash kétféle ciklust ismer:

  • Ismételj meg néhány parancsot egy lista minden elemére,
  • Ismételj meg néhány parancsot amíg valamilyen feltétel igaz (vagy hamis).

For ciklusok

Egy lista elemein való iteráláshoz a for ciklust használjuk.

for varname in words; do COMMANDS; done

A words szófelbontással és fájlnév-kiterjesztéssel bővül (ezekről az idézés fogalmában tanultunk). Minden szó sorban hozzárendelődik a varname változóhoz, és a COMMANDS parancsok végrehajtódnak.

Íme néhány példa, amelyek megmutatják, mikor lehet hasznos a for ciklus

  • Hajts végre néhány parancsot egy fájlcsoporton.

    # source all the bash library files in the current directory
    for file in ./*.bash; do
        source "$file"
    done
    
  • Hajts végre valamilyen parancsot egy szkript vagy függvény minden paraméterén.

    for arg in "$@"; do
        echo "argument: ${arg}"
    done
    
  • Hajts végre valamilyen parancsot egy parancs kimenetének minden whitespace-szel elválasztott szavára.

    for i in $(seq 10); do
        echo "${i} squared is $((i * i))"
    done
    

    Később látni fogunk néhány figyelmeztetést ezzel a stílussal kapcsolatban.

Aritmetikai for ciklus

A Bash-nek valóban van aritmetikai ciklusa. Ez némileg ismerős lesz más programozási nyelvekből.

for ((INITIALIZATION; CONDITION; INCREMENT)); do COMMANDS; done

A dupla zárójel a Bash-ben aritmetikai kontextust jelent (a Bash-aritmetikáról később egy másik fogalomban lesz szó). A fenti, seq-et használó példa így írható fel:

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

Mikor ne használjuk a for ciklust

Ne olvass sorokat for-ral.

Ez egy gyakran látott antiminta: a cat kimenetén iterálunk.

for line in $(cat some.file); do 
    do_something_with "$line"
done

Ez két szempontból is hibás.

  1. A parancsbehelyettesítés nincs idézőjelben, ezért szófelbontásnak van kitéve. A szófelbontás alapértelmezés szerint whitespace karaktereknél választ el, nem csak sortöréseknél. Ez a for ciklus a fájl szavain iterál, nem a sorain.
  2. A parancsbehelyettesítés nincs idézőjelben, ezért fájlnév-kiterjesztésnek van kitéve. A fájl minden szava glob mintaként lesz illesztve.

Ahogy az idézés fogalmában tanultuk, a szófelbontás az IFS változóval szabályozható, a fájlnév-kiterjesztés pedig kikapcsolható. De ez általában törékeny megoldás. A for nem megfelelő módszer egy fájl sorainak bejárására. A fájl beolvasásának idiomatikus módja a while ciklus.

While ciklusok

A while segítségével parancsok sorozatát ismételheted amíg valamilyen feltétel igaz.

while CONDITION_COMMANDS; do COMMANDS; done

Ahogy az if esetében is (ahogy a feltételes elágazások fogalmában tanultuk), nincs különleges szintaxis a CONDITION_COMMANDS számára. A parancslista kilépési állapota dönti el, hogy „igaz” vagy „hamis”.

Ciklusok vezérlése

A break parancs kilép a ciklusból. A vezérlés a ciklus done lezárója utáni paranccsal folytatódik.

A continue parancs a ciklus következő iterációjára ugrik.

Fájl sorainak beolvasása

Ahogy említettük, a fájl beolvasásának idiomatikus módja a while ciklus.

while IFS= read -r line; do
    do_something_with "$line"
done < some.file
  • A fájl tartalma a < átirányítással lesz a ciklus bemenete.

  • A read parancs „igaz” értékkel tér vissza, ha egy teljes sort tud olvasni a bemenetéről. Amikor a bemenet elfogy, vagy ha az utolsó sor végén nincs záró sortörés, akkor a read „hamis” értékkel tér vissza.

    • A valóban idiomatikus módja egy fájl sorai beolvasásának, még akkor is, ha az utolsó sor nem végződik sortöréssel:

      while IFS= read -r line || [[ -n "$line" ]]; do ...
      
  • A -r kapcsoló azt mondja a read-nek, hogy ne helyettesítse a backslash-szekvenciákat: a backslash egyszerű karakter.

  • Az IFS= csak a read parancs időtartamára rendeli az üres stringet az IFS-hez. Ez átmenetileg kikapcsolja a szófelbontást, így a bejövő szövegsor elején vagy végén lévő whitespace megmarad.

Until

Az until szerkezet parancsok sorozatát ismétli, amíg valamilyen feltétel hamis. A ciklus addig ismétlődik, amíg a feltétel igazzá nem válik.

until CONDITION_COMMANDS; do COMMANDS; done

Ritka az until használata. Gyakoribb a „while not” ciklus használata.

while ! CONDITION_COMANDS; do ...

Végtelen ciklusok

Néha örökké szeretnél ciklust futtatni. Íme két módszer erre.

  1. egy while ciklus olyan feltétellel, amelynek kilépési állapota mindig sikeres

    while true; do ...
    
  2. egy aritmetikai for ciklus üres kifejezésekkel

    for ((;;)); do ...
    

Do-While

Nincs külön do-while szerkezet, de ugyanezt a hatást elérheted:

while true; do
    COMMANDS

    if END_CONDITION; then
        break
    fi
done
Szerkesztés GitHubon A hivatkozás új ablakban vagy lapon nyílik meg