Elektronenblitz63 Homepage
Creative Commons License

Bash-Skripte

Skripte bieten eine unerschöpfliche Vielfalt an individuellen Lösungsmöglichkeiten um bestimmte Aufgaben zu erledigen oder zu automatisieren. Hier eine kleine Sammlung.

Folgende Seiten mit weiterführenden Links erleichten den Einstieg in die Bash-Programmierung und erklären grundlegende Funktionen:

Shell/Bash-Skripting-Guide_für_Anfänger (uu-Wiki)
Tim Bormann - Shell-Befehle (Sammlung)

praktische Anwendungen

Die hier gezeigten Programme, die ich im Rahmen meiner Möglichkeiten erstellt habe, laufen auf meinem System unter GNOME einwandfrei. Für andere Desktopoberflächen wie z.B. KDE, müssen u.U. einige Befehle für die Benachrichtigungsanzeige angepasst werden.

Übersicht:

1. Diskette einbinden (Diskettenlaufwerke mounten und auch wieder aushängen)
2. Netzwerktraffic aufzeichnen (Protokollierung des verbrauchtem Datenvolumens)
3. Onlinezeit überwachen (Timer/Alarmgeber für Volumentarife)
4. LAN/WLAN Umschalter
5. WLAN Signalauswertung (genaue Anzeige der Signalstärke)

1. Diskette einbinden

Bei neueren Computern fehlt im allgemeinen ein Diskettenlaufwerk. Um Bootprobleme zu vermeiden wurden die entsprechenden Systemdateien angepasst, so dass bei Systemstart nicht mehr nach einem Diskettenlaufwerk gesucht wird. Allerdings kann ein vorhandenes Laufwerk nachträglich nicht so ohne weiteres ohne root-Rechte eingebunden werden. Durch einen Downgrade der entsprechenden Systemdatei (udisks) kann dies behoben werden, allerdings funktioniert das nicht immer einwandfrei oder verursacht Probleme mit anderen Speichermedien.

Folgendes Skript ermöglicht die Einbindung und das sichere Aushängen des Diskettenlaufwerks als normaler User der Gruppe plugdev.

Beispiele
Anwendung für ein int. Diskettenlaufwerk
Anwendung für ein ext. USB Floppy-Laufwerk (optimiertes Skript)

Folgende Pakete werden zusätzlich benötigt und müsssen nachinstalliert werden:

* pmount
* libnotify-bin

#!/bin/bash
### mount/unmount floppy
### Elektronenblitz63 - ubuntuusers.de 2010
### published under GPL V3

# libnotify settings
TITLE="Diskettenlaufwerk"
MOUNT="Diskette eingebunden"
UNMOUNT="Diskette kann entfernt werden"
ERROR="keine Diskette im Laufwerk !"
LOGO=/usr/share/icons/gnome/scalable/devices/media-floppy.svg

# Abfrage Status Diskette geladen
floppy_mount="`mount -l | egrep -wo '/dev/fd0'`"

if [ "$floppy_mount" = "/dev/fd0" ]; then
pumount /media/Diskette notify-send -i $LOGO "$TITLE" "$UNMOUNT"
exit

else
pmount -w /dev/fd0 /media/Diskette
fi

floppy_mount="`mount -l | egrep -wo '/dev/fd0'`"

if [ "$floppy_mount" = "/dev/fd0" ]; then
notify-send -i $LOGO "$TITLE" "$MOUNT"
else
notify-send -i $LOGO "$TITLE" "$ERROR"
fi
exit

Top

2. Netzwerktraffic aufzeichnen

Folgendes Skript protokolliert das aufkommende Datenvolumen auf den voreingestellten Schnittstellen und legt die Daten für jeden Monat in einer Logdatei ab. Zusätzlich kann über einen Klickbutton (Anwendungsstarter) das verbrauchte Datenvolumen der aktuellen Sitzung angezeigt werden.

Beispiele
Anwendung für einen DSL-Volumentarif

Folgendes Paket wird zusätzlich benötigt und muss nachinstalliert werden:

* libnotify-bin

Zwei Anwendungsstarter anlegen:
Rechtsklick auf das obere Panel > hinzufügen > "Benutzerdefinierter Anwendungssarter"

Befehl für die Direktanzeige:

$ ./traffic.sh -s

Befehl um die Daten in die Logdateien zu übernehmen und das System neu zu starten oder die Sitzung zu beenden:

$ ./traffic.sh

Dann noch passende Icons auswählen, fertig. Der Rechner muss dann mit dem zweiten Anwendungsstarter heruntergefahren werden um vorher das Skript auszuführen, ansonsten funktioniert das nicht. Der automatische Start des Skripts über die entsprechenden Runlevel 0 & 6 (siehe Dienste) funktioniert leider nicht richtig, bzw. das Skript wird nicht vollständig ausgeführt.


#!/bin/bash
### LAN/WLAN Traffic Report
### Elektronenblitz63 - ubuntuusers.de 2010
### published under GPL V3

# libnotify settings
TITLE="Datenvolumen LAN/WLAN:"
LOGO=/usr/share/icons/hicolor/scalable/apps/update-manager.svg

# Variablen / Schnittsellen ggf. anpassen
liface=eth
wiface=wlan

# Variablen
sreenoutput=0
lantrafficRX=0
lantrafficTX=0
wlantrafficRX=0
wlantrafficTX=0
Filedate="`date | awk {'print $3$6'}`"
Filedate_1="`date | awk {'print $3, $6'}`"
Datum="`date`"

# Startparameter
if [ "$1" = "-s" ]; then
sreenoutput=1
fi

# Namen und Pfad der Protokolldatei
File="Traffic"
Filesum="_Summe"
Fileext=".log"
Path="`pwd`/Traffic_Log"

# Schnittsellen prüfen / Abfragen
laniface="`ifconfig | grep $liface | awk {'print $1'}`"
wlaniface="`ifconfig | grep $wiface | awk {'print $1'}`"

if [ "$laniface" = "" ]; then
lantraffic=0
else
lantraffic="`ifconfig $laniface | grep 'RX bytes' | awk {'print $1,$2,$3,$4,$5,$6,$7,$8'}`"
lantrafficRX="`ifconfig $laniface | grep 'RX bytes' | awk {'print $2'} | tr -d 'bytes:'`"
lantrafficTX="`ifconfig $laniface | grep 'RX bytes' | awk {'print $6'} | tr -d 'bytes:'`"

if [ "$wlaniface" = "" ]; then
wlantraffic=0
else
wlantraffic="`ifconfig $wlaniface | grep 'RX bytes' | awk {'print $1,$2,$3,$4,$5,$6,$7,$8'}`"
wlantrafficRX="`ifconfig $wlaniface | grep 'RX bytes' | awk {'print $2'} | tr -d 'bytes:'`"
wlantrafficTX="`ifconfig $wlaniface | grep 'RX bytes' | awk {'print $6'} | tr -d 'bytes:'`"
fi

# Berechnung kB, MB, GB
sumbyte=`expr $lantrafficRX + $lantrafficTX + $wlantrafficRX + $wlantrafficTX`
sumKbyte=`expr $sumbyte \/ 1024`
sumMbyte=`expr $sumKbyte \/ 1024`
sumGbyte=`expr $sumMbyte \/ 1024`

# Ausgabe auf Bildschirm / Libnotify
if [ "$sreenoutput" = 1 ]; then

LogFile="$Path"/"$File""$Filesum"_"$Filedate""$Fileext"
subtotal="`cat $LogFile | awk {'print $9'} | tr -d '~'`"
subtotal=`expr $subtotal + $sumMbyte`
notify-send -i $LOGO "$TITLE" "$sumKbyte kB / ~$sumMbyte MB / ~$sumGbyte GB / aktuell Monat $subtotal MB"
exit
else

logdir="`find $Path | grep Sum`"
if [ "$logdir" = "" ]; then
mkdir Traffic_Log
LogFile="$Path"/"$File""$Filesum"_"$Filedate""$Fileext"
echo "Verbrauchtes Datenvolumen $Filedate_1: 0 kB - entspricht ~0 Mega-Byte Daten (Download & Upload)" > $LogFile
fi

# Ausgabe in Protokolldatei
LogFile="$Path"/"$File"_"$Filedate""$Fileext"
echo "Datenvolumen am $Datum:" >> $LogFile
echo "LAN-Schnittselle: $lantraffic" >> $LogFile
echo "WLAN-Schnittstelle: $wlantraffic" >> $LogFile
echo "Insgesamt wurden bei dieser Sitzung $sumbyte Bytes übertragen" >> $LogFile
echo "Das entspricht $sumKbyte kB - ~$sumMbyte MB - ~$sumGbyte GB" >> $LogFile
echo "-" >> $LogFile

# Summe Monat / Ausgabe in Protokolldatei 2
LogFile="$Path"/"$File""$Filesum"_"$Filedate""$Fileext"
subtotal="`cat $LogFile | awk {'print $5'}`"
sumKbyte=`expr $sumKbyte + $subtotal`
sumMbyte=`expr $sumKbyte \/ 1024`
echo "Verbrauchtes Datenvolumen $Filedate_1: $sumKbyte kB - entspricht ~$sumMbyte Mega-Byte und ~$sumGbyte GB Daten (Download & Upload)" > $LogFile

# Job finished / System herunterfahren / neu starten
gnome-session-save --shutdown-dialog

fi
fi
exit


Top

3. Onlinezeit überwachen

Das Skript ist universell anwendbar und z.B. für UMTS-Verbindungen im Zusammenhang mit einem Volumentarif gedacht. Das Skript muss mit drei Strartparametern, der zu überwachenden Schnittstelle, dem gewünschten Zeitlimit in Minuten und der Zeit für eine Alarmwiederholung (optional), aufgerufen werden. Wird der dritte Wert nicht angegeben erfolgt eine Alarmwiederholung (Klang) im Minutentakt.

Beispiele
Anwendung für eine UMTS-Verbindung

Der Aufruf sieht folgendermaßen aus:

$ ./Skriptname.sh ppp0 15 2

Folgende Pakete werden zusätzlich benötigt und müsssen nachinstalliert werden:
* mplayer-nogui
* libnotify-bin

#!/bin/bash
## Online-Timer
## Elektronenblitz63 ubuntuusers.de 2010
## published under GPL v3

# Libnotify settings
TITLE="Online-Timer:"
WARNING="Zeitlimit erreicht"
ERROR="Fehler - Parameter nicht angegeben"
LOGO=/usr/share/icons/hicolor/48x48/apps/gnome-obex-server.png

# Sounds
LoginSound=/usr/share/sounds/ubuntu/stereo/service-login.ogg
LogoutSound=/usr/share/sounds/ubuntu/stereo/service-logout.ogg
WarnSound=/usr/share/gnome-games/sounds/gnometris.ogg

# allg. Variablen
Iface=$1
Warntime=$2
connect=3
Starttime=$(date +%s)
Timeexceed=1
Pause=10

# Prüfung Übergabeparameter
if [ "$1" = "" ]; then
echo "Schnittstelle und/oder Zeitlimit wurde nicht angegeben"
notify-send -i $LOGO "$TITLE" "$ERROR"
exit

elif [ "$2" = "" ]; then
echo "Schnittstelle und/oder Zeitlimit wurde nicht angegeben"
notify-send -i $LOGO "$TITLE" "$ERROR"
exit
fi

# Zeit Alarmwiederholung
if [ "$3" = "" ]; then
Repetition=1
else
Repetition=$3
fi
# Loop
while true; do

# Startzeit bestimmen
ZeitAktuell=$(date +%s)
Differenz=$(($ZeitAktuell - $Starttime))
Minuten=$(($Differenz / 60))

# Default-Gateway und Schnittstelle abfragen
route="`route -n | egrep UG | awk {'print $8'}`"

# Verbindungsprüfung
if [ "$connect" = 1 ]; then
connect=1

elif [ "$route" = $Iface ]; then
notify-send -i $LOGO "$TITLE" "Verbindung aufgebaut, starte Timer"
mplayer -quiet $LoginSound
connect=1
Starttime=$(date +%s)
Pause=20
sleep $Pause
fi

if [ "$connect" = 0 ]; then
connect=0
Starttime=$(date +%s)

elif [ "$route" != $Iface ]; then
notify-send -i $LOGO "$TITLE" "keine Verbindung"
mplayer -quiet $LogoutSound
connect=0
Timeexceed=1
WARNING="Zeitlimit erreicht"
Pause=10
sleep $Pause
fi

# Zeitprüfung
if [ "$Warntime" = $Minuten ]; then
notify-send -i $LOGO "$TITLE" "$WARNING"
mplayer -quiet $WarnSound
Warntime=$[$Warntime + $Repetition]
Timeexceed=$[$Timeexceed + $Repetition]
fi

if [ "$Timeexceed" = 1 ]; then
WARNING="Zeitlimit überschritten"
sleep $Pause

else
WARNING="Zeitlimit um $Timeexceed Minuten überschritten"
sleep $Pause
fi

done
exit


Top

4. LAN/WLAN Umschalter

Über das Skript werden die Treibermodule für die LAN- bzw. WLAN-Karte im Wechsel entladen und wieder geladen. Das kann bei Laptops die nicht mit dem mac802.11 Syubsystem und rfkill arbeiten hilfreich sein. Oft funktioniert auch der Schalter oder Sondertaste um WLAN abzuschalten nicht.

Hier im Beispiel werden die Treiber für eine Broadcom WLAN-Karte (Station-Treiber/Modul wl) und auch Broadcom LAN-Karte (Modul b44/ssb/mii) verwendet. Die benötigten Treibermodule können im Konfigurationsblock des Skripts angepasst werden.

Das Skript erfordert root-Rechte! Über eine entsprechende Konfiguration kann die Kennwortabfrage jedoch umgangen und die Ausführung des Skripts bequem über eine Tastenkombination gesteuert werden.

Beispiele
Anwendung auf einem Asus eee-PC 1001p

Folgendes Paket wird zusätzlich benötigt und muss nachinstalliert werden:

* libnotify-bin

#!/bin/bash
### aktiviert/deaktiviert LAN und WLAN im Wechsel
### Elektronenblitz63 -ubuntuusers.de 2010
### published under GPL V3

# libnotify settings
TITLE="Verbindungen"
LON="LAN aktiviert - WLAN deaktiviert"
LOFF="LAN deaktiviert - WLAN aktiviert"
WLANLOGO=/usr/share/icons/gnome/scalable/devices/network-wired.svg
LANLOGO=/usr/share/icons/gnome/scalable/devices/network-wireless.svg

# Module die entladen/geladen werden sollen
lanmodul1=b44
submodul1=ssb
submodul2=mii
wlanmodul=wl

# Abfrage Status/LAN-Modul geladen
module_present="`lsmod | egrep -wo $lanmodul1`"

# deaktiviert LAN - aktiviere WLAN
if [ "$module_present" = $lanmodul1 ]; then
modprobe -rf $lanmodul1
modprobe -rf $submodul1
modprobe -rf $submodul2
modprobe $wlanmodul
notify-send -i $LANLOGO "$TITLE" "$LOFF"

# deaktiviert WLAN - aktiviere LAN
else
modprobe -rf $wlanmodul
modprobe -rf submodul1
modprobe $lanmodul1
notify-send -i $WLANLOGO "$TITLE" "$LON"
fi
exit


Top

5. Signalauswertung

Über das Skript kann die Signalstärke einer bestehenden WLAN Verbindung zeitnah ausgewertet werden um z.B. den Standort der Antenne oder des Routers zu optimieren. Weitere Informationen zur Datenübertragung werden ebenfalls angezeigt.

Das Skript muss mit drei Übergabeparametern aufgerufen werden, der verwendeten Schnittstelle (z.B. wlan0), der Zeit in Sekunden für die Abfrage (0.5 - 3 Sekunden) und der maximal auswertbaren Signalstärke (100/70). Welcher Maximalwert vom System verwendet wird kann vorab mittels iwconfig abgefragt werden. Der Aufruf sieht folgendermaßen aus:

$ ./Skriptname.sh wlan0 2 100

#!/bin/bash
### Empfangspegel anzeigen
### Elektronenblitz63 - ubuntuusers.de 2010
### published under GPL V3

# Parameter
iface=$1
pause=$2
maxlevel=$3

name="unknown"
apmac="unknown"
connection="unknown"

# loop
while true; do
clear

# Informationen holen
name="`iwconfig $iface | grep ESSID | awk {'print $4'}`"
apmac="`iwconfig $iface | grep Access | awk {'print $4,$5,$6'}`"
connection="`iwconfig $iface | egrep 'Rx|Tx'`"
signal="`iwconfig $iface | grep Link | awk {'print $2'} | tr -d Quality:=/ | sed 's/\(.*\)'$maxlevel'/\1/'`"

quality="`iwconfig $iface | grep Link`"
sig="$signal"

color="32"

# Signalstärke Null?
if [ "$sig" = "" ]; then
signal="0"
color="31"
name="unknown"
apmac="unknown"
connection="unknown"

# Farbwechsel Signalbar
elif [ "$signal" -lt "45" ]; then
color="31"

elif [ "$signal" -lt "75" ]; then
color="33"
fi

# Definition Signalbar
if [ "$maxlevel" = "100" ]; then
signalbar="0---:----1----:----2----:----3----:----4----:----5----:----6----:----7----:----8----:----9----:----|"
else
signalbar="0---:----1----:----2----:----3----:----4----:----5----:----6----:----7|"
fi

#Ausgabe Verbindungsinformatinen
echo Signalauswertung - elektronenblitz63 - ubuntuusers.de - 2010
echo
echo Empfangsstärke WLAN-Schnittstelle $iface
echo
echo Verbunden mit $name - $apmac
echo
echo Verbindung
echo $connection | awk {'print $1,$2,$3,$4,$5,$6'}
echo
echo Datenübertragung
echo $connection | awk {'print $7,$8,$9,$10,$11,$12,$13,$14,$15'}
echo $connection | awk {'print $16,$17,$18,$19,$20,$21,$22'}
echo

# Ausgabe Signalbar
echo -e "\033[0;1;"$color"m ${signalbar:0:$sig}> ($signal)"
echo
echo -e "\033[0;0m $quality"

sleep $pause
done
exit


Top