Beispiele für Shellskripts
Datei verlängern Weil immer wieder danach gefragt wird: "Wie hänge ich den Inhalt einerVariablen an eine Datei an?": ( cat file1 ; echo "$SHELLVAR" ) > file2 TelefonbuchTelefonverzeichnis mit Hier-Dokument. Aufruf tel Name [Name ..]:
if [ $# -eq 0 ]
then
echo "Usage: `basename $0` Name [Name ..]"
exit 2
fi
for SUCH in $*
do
if [ ! -z $SUCH ] ; then
grep $SUCH << "EOT"
Hans 123456
Fritz 234561
Karl 345612
Egon 456123
EOT
fi
done
Kompakte Auflistung des Inhalts eines ganzen Dateibaums
Dies ist ein rekursives Programm. Damit es klappt, muß das folgende Skript
dir über PATH erreichbar sein. Aufruf: dir Anfangspfad.
if test $# -ne 1
then
echo "Usage: dir Pfad"
exit 2
fi
cd $1
echo
pwd
ls -CF
for I in *
do
if test -d $I
then
dir $I
fi
done
Auflisten des Dateibaums in grafischer Form
wobei zur Dateiauswahl alle Optionen des find-Kommandos zur Verfügung stehen.
Aufruf z.B. tree . für alle Dateien oder tree . -type d
für Directories ab dem aktuellen Verzeichnis.
# find liefert die vollständigen Pfadnamen (temporäre Datei).
# Mit ed werden die "/"-Zeichen erst zu "|---- " expandiert
# und dann in den vorderen Spalten aus "|---- " ein Leerfeld
# " |" gemacht.
if test $# -lt 1
then
echo "Usage: tree Pfadname [Pfadname ...] [find-Options]"
else
TMPDAT=$0$$
find $@ -print > $TMPDAT 2>/dev/null
ed $TMPDAT << "EOT" >/dev/null 2>/dev/null
1,$s/[^\/]*\//|---- /g
1,$s/---- |/ |/g
w
q
EOT
cat $TMPDAT
rm $TMPDAT
fi
Mit dem Stream-Editor sed kann das sogar noch kompakter formuliert werden:
if [ $# -lt 1 ]
then
echo "Usage: tree Pfadname [Pfadname ...] [find-Options]"
else
find $@ -print 2>/dev/null | \
sed -e '1,$s/[^\/]*\//|---- /g' -e '1,$s/---- |/ |/g'
fi
Argumente mit J/N-Abfrage ausführen
Das folgende Skript führt alle Argumente nach vorheriger Abfrage aus. Mit
"j" wird die Ausführung bestätigt, mit "q" das Skript
abgebrochen und mit jedem anderen Buchstaben (in der Regel "n") ohne Ausführung
zum nächsten Argument übergegangen. Ein- und Ausgabe erfolgen immer über
das Terminal(-fenster), weil /dev/tty angesprochen wird. Das Skript wird
anstelle der Argumentenliste bei einem anderen Kommando eingesetzt, z. B. Löschen
mit Nachfrage durch rm $(pick *)
# pick - Argumente mit Abfrage liefern
for I ; do
echo "$I (j/n)? \c" > /dev/tty
read ANTWORT
case $ANTWORT in
j*|J*) echo $I ;;
q*|Q*) break ;;
esac
done </dev/tty
Sperren des Terminals während man kurz weggeht
Nach Aufruf von lock wird ein Kennwort eingegeben und das Terminal blockiert.
Erst erneute Eingabe des Kennwortes beendet die Prozedur. Die Gemeinheit dabei
ist, daß sich bei jeder Fehleingabe die Wartezeit verdoppelt.
echo "Bitte Passwort eingeben: \c"
stty -echo # kein Echo der Zeichen auf dem Schirm
read CODE
stty echo
tput clear # BS loeschen
trap "" 2 3
banner " Terminal "
banner " gesperrt "
MATCH=""
DELAY=1
while [ "$MATCH" != "$CODE" ]
do
sleep $DELAY
echo "Bitte Passwort eingeben: \c"
read MATCH
DELAY='expr $DELAY \* 2` # doppelt so lange wie vorher
done
echo
Dateien im Pfad suchen
Das folgende Skript bildet das Kommando "which" nach. Es sucht im aktuellen
Pfad (durch PATH spezifiziert) nach der angegebenen Datei und gibt die Fundstelle
aus. An diesem Skript kann man auch eine Sicherheitsmaßnahme sehen. Für
den Programmaufruf wird der Pfad neu gesetzt, damit nur auf Programme aus /bin
und /usr/bin zugegriffen wird. Bei Skripts, die vom Systemverwalter für die
Allgemeinheit erstellt werden, sollte man entweder so verfahren oder alle Programme
mit absolutem Pfad aufrufen.
#!/bin/sh
# Suchen im Pfad nach einer Kommando-Datei
OPATH=$PATH
PATH=/bin:/usr/bin
if [ $# -eq 0 ] ; then
echo "Usage: which kommando" ; exit 1
fi
for FILE
do
for I in `echo $OPATH | sed -e 's/^:/.:/' -e 's/::/:.:/g \ -e 's/:$/:./'`
do
if [ -f "$I/$FILE" ] ; then
ls -ld "$I/$FILE"
fi
done
done
Berechnung von Primfaktoren einer Zahl:
echo "Zahl eingeben: \c"; read ZAHL
P=2
while test `expr $P \* $P` -le $ZAHL; do
while test `expr $ZAHL % $P` -ne 0; do
if test $P -eq 2; then
P=3
else
P=`expr $P + 2`
fi
done
ZAHL=`expr $ZAHL / $P`
echo $P
done
if test $ZAHL -gt 1; then
echo $ZAHL
fi
echo ""
Berechnung des Osterdatums nach C.F. Gauss
if [ $# -eq 0 ] ; then
echo "Osterdatum fuer Jahr: \c"; read JAHR
else
JAHR="$1"
fi
G=`expr $JAHR % 19 + 1`
C=`expr $JAHR / 100 + 1`
X=`expr \( $C / 4 - 4 \) \* 3`
Z=`expr \( $C \* 8 + 5 \) / 25 - 5`
D=`expr $JAHR \* 5 / 4 - $X - 10`
E=`expr \( $G \* 11 + $Z - $X + 20 \) % 30`
if test $E -lt 0; then
$E=`expr $E + 30`
fi
if [ $E -eq 25 -a $G -gt 11 -o $E -eq 24 ] ; then
E=`expr $E + 1`
fi
TAG=`expr 44 - $E`
if [ $TAG -lt 21 ] ; then
TAG=`expr $TAG + 30`
fi
TAG=`expr $TAG + 7 - \( $D + $TAG \) % 7`
if [ $TAG -gt 31 ] ; then
TAG=`expr $TAG - 31`
MON=4
else
MON=3
fi
echo "Ostern $JAHR ist am ${TAG}.${MON}.\n"
Statt des expr-Befehls kann bei der Bash auch das Konstrukt
$(( ... )) verwendet werden. Das Programm sieht dann so aus:
if [ $# -eq 0 ] ; then
echo "Osterdatum fuer Jahr: \c"; read JAHR
else
JAHR="$1"
fi
G=$(($JAHR % 19 + 1))
C=$(($JAHR / 100 + 1))
X=$((\( $C / 4 - 4 \) \* 3))
Z=$((\( $C \* 8 + 5 \) / 25 - 5))
D=$(($JAHR \* 5 / 4 - $X - 10))
E=$((\( $G \* 11 + $Z - $X + 20 \) % 30))
if test $E -lt 0; then
$E=$(($E + 30))
fi
if [ $E -eq 25 -a $G -gt 11 -o $E -eq 24 ] ; then
E=$(($E + 1))
fi
TAG=$((44 - $E))
if [ $TAG -lt 21 ] ; then
TAG=$(($TAG + 30))
fi
TAG=$(($TAG + 7 - \( $D + $TAG \) % 7))
if [ $TAG -gt 31 ] ; then
TAG=$(($TAG - 31))
MON=4
else
MON=3
fi
echo "Ostern $JAHR ist am ${TAG}.${MON}.\n"
Wem die Stunde schlägt
Wer im Besitz einer Soundkarte ist, kann sich eine schöne Turmuhr,
einen Regulator oder Big Ben basteln. Die folgende "Uhr" hat Stunden- und
Viertelstundenschlag. Damit das auch klappt, ist ein Eintrag in der
crontab nötig:
0,15,30,45 * * * * /home/sbin/turmuhr
So wird das Skript turmuhr alle Viertelstunden aufgerufen. Es werden zwei
Sounddateien verwendet, hour.au für den Stundenschlag und quater.au
für den Viertelstundenschlag. Statt des Eigenbau-Programms audioplay
kann auch der sox verwendet werden oder man kopiert die Dateien einfach nach
/dev/audio. Die Variable VOL steuert die Lautstärke.
#!/bin/sh
BELL=/home/local/sounds/hour.au
BELL1=/home/local/sounds/quater.au
PLAY=/usr/bin/audioplay
VOL=60
DATE=`date +%H:%M`
MINUTE=`echo $DATE | sed -e 's/.*://'`
HOUR=`echo $DATE | sed -e 's/:.*//'`
if [ $MINUTE = 00 ]
then
COUNT=`expr \( $HOUR % 12 + 11 \) % 12`
BELLS=$BELL
while [ $COUNT != 0 ];
do
BELLS="$BELLS $BELL"
COUNT=`expr $COUNT - 1`
done
$PLAY -v $VOL -i $BELLS
elif [ $MINUTE = 15 ]
then $PLAY -v $VOL -i $BELL1
elif [ $MINUTE = 30 ]
then $PLAY -v $VOL -i $BELL1 $BELL1
elif [ $MINUTE = 45 ]
then $PLAY -v $VOL -i $BELL1 $BELL1 $BELL1
else
$PLAY -v $VOL -i $BELL1
fi
|