while: Unterschied zwischen den Versionen

Aus Mikiwiki
Zur Navigation springen Zur Suche springen
Zeile 60: Zeile 60:
   local OLD_IFS="${IFS}"
   local OLD_IFS="${IFS}"
   IFS=":"
   IFS=":"
   local ARR=( $1 )
   local ARR=( $1 ) ; shift
  IFS="${OLD_IFS}"
  local PREFIX="$*" ; [ -n "${PREFIX}" ] && PREFIX="${PREFIX} > "
   local SECONDS=$((  (ARR[0] * 60 * 60) + (ARR[1] * 60) + ARR[2]  ))
   local SECONDS=$((  (ARR[0] * 60 * 60) + (ARR[1] * 60) + ARR[2]  ))
   local START=$(date +%s)
   local START=$(date +%s)
Zeile 70: Zeile 72:
     CUR=$(date +%s)
     CUR=$(date +%s)
     LEFT=$((END-CUR))
     LEFT=$((END-CUR))
     printf "\r%02d:%02d:%02d" \
     printf "\r%s%02d:%02d:%02d" \
             $((LEFT/3600)) $(( (LEFT/60)%60)) $((LEFT%60))
             "${PREFIX}" $((LEFT/3600)) $(( (LEFT/60)%60)) $((LEFT%60))
     sleep 1
     sleep 1
     done
     done
  IFS="${OLD_IFS}"
   echo "        "
   echo "        "
  }
  }

Version vom 23. März 2011, 14:23 Uhr

Der Shell-Befehl while bewirkt eine Schleife, welche solange wiederholt wird wie eine anfangs stehende Bedingung erfolgreich ist (also Exit-Status 0 liefert). Die Abwicklung der Schleife wird dabei vom Exit-Status eines Befehls gesteuert.

Syntax

Die Shell führt Befehlsliste2 nur dann aus, wenn der letzte Befehl aus Befehlsliste1 den Exit-Status 0 geliefert hat. Nach jedem Schleifendurchlauf führt die Shell Befehlsliste1 erneut aus.

while Befehlsliste1
  do
    Befehlsliste2
  done

Verwendung

Alle 30 Sekunden soll ein "x" auf den Bildschirm geschrieben werden. Das kann nützlich sein, um eine SSH-Verbindung auf einem zweiten Bildschirm am Leben zu erhalten, wenn etwa auf dem Router "dialer idle-timeout 90" eingestellt ist.

$ while true; do echo -n "x"; sleep 30; done

...

$ x=0
$ while test $x -lt 3
> do
> let x+=1
> echo ${x}
> done
1
2
3

$ while true
> do
> banner $(date '+%H:%M')
> sleep 60
> done

Mit der folgenden Schleife können beliebig viele Parameter ausgewertet werden. Durch "( $@ )" wird dabei die Parameterkette an den Leerzeichen in einzelne Abschnitte aufgespalten un nacheinander in ein eindimensionales Array gespeichert.

#!/bin/bash
declare -i i=0
array=( $@ )
while [ $i -le $# ]; do
  echo "Inhalt von array[$i]: ${array[$i]}"
  i=$i+1
done

$ ./while.sh 1 2 "3 4 5"
Inhalt von array[0]: 1
Inhalt von array[1]: 2
Inhalt von array[2]: 3
Inhalt von array[3]: 4

Auf den ersten Eintrag könnte auch mit "echo $array[0]" zugegriffen werden.

Countdown

function countdown
{
  local OLD_IFS="${IFS}"
  IFS=":"
  local ARR=( $1 ) ; shift
  IFS="${OLD_IFS}"
  local PREFIX="$*" ; [ -n "${PREFIX}" ] && PREFIX="${PREFIX} > "
  local SECONDS=$((  (ARR[0] * 60 * 60) + (ARR[1] * 60) + ARR[2]  ))
  local START=$(date +%s)
  local END=$((START + SECONDS))
  local CUR=$START

  while [[ $CUR -lt $END ]]
    do
    CUR=$(date +%s)
    LEFT=$((END-CUR))
    printf "\r%s%02d:%02d:%02d" \
            "${PREFIX}" $((LEFT/3600)) $(( (LEFT/60)%60)) $((LEFT%60))
    sleep 1
    done
  echo "        "
}

countdown "00:00:30"