bash von der Idee zum Script Tutorial Teil 15

Jedes bash Script beginnt mit einer Idee, wie ein Problem zu lösen ist. Ich will dir in diesen Post zeigen, wie sich so etwas entwickelt.

bash Logo - Idee
Dr. Dirk Colbry, Michigan State
Gnu-bash-logoCreative Commons Attribution-NonCommercial-ShareAlike 4.0 International License . loading=
1Einführung
2Der bash Prompt
3key bindings
4Der Startvorgang
5Environment Variablen
6builtin commands
7Arbeiten mit Dateien
8nano
9bash Scripting
10Variablen
11Verzweigungen (if)
12Schleifen
13Kommandozeilenparameter
14exit Codes bash Tutorial Teil 14
15von der Idee zum Script
16grep
17Piping und Redirection
18tee

Die Idee

Ich möchte dir das am Beispiel des SD-Karten Tests demonstrieren. Der Grundgedanke ist, wiederkehrende Aufgaben zu automatisieren.

In vielen Fällen ist es sinnvoll, wenn du den gesamten Ablauf einmal mit diskreten Kommandos von Hand durchspielst. Damit machst du eine Bestandsaufnahme, legst die Kommandos mit ihren Parametern und ihre Reihenfolge fest.

Nachdem die MicroSD Karte im USB-Reader eingelegt ist, zerfällt der Geschwindigkeitstest in folgende Schritte:

Schritt 1: Partition löschen und anlegen

Jede MicroSD Karte wird mit einer Partition mit VFAT Filesystem ausgeliefert. Diese müssen wir erstmal loswerden und eine neue ext4 Partition anlegen. Dies hatte ich immer manuell gemacht, bis ich auf das Programm sfdisk aufmerksam wurde, dass wie fdisk arbeitet, aber für den Einsatz in Scripts ausgelegt ist.

Falls sfdisk auf deinem Raspberry Pi nicht installiert ist, musst du es nachinstallieren.

Das Löschen der Partition erfolgt mit der Zeile

sfdisk --delete -w ${DEVICE} 1 && sync

${DEVICE} enthält das Devicefile der MicroSD Karte, das im Script später als Kommandozeilenparameter übergeben wird.

Die neue Partition wird danach mit

echo ",," |sfdisk ${DEVICE} && sync

angelegt. Da sfdisk für die Partitionsanlage Tastatureingaben erwartetet, pipen wir diese mit dem vorangestellten echo einfach ins Kommando hinein. das nachlaufende sync dient dazu, alle Änderungen auf die Speicherkarte zu schreiben.

Schritt 2: Filesystem erstellen

Die Partition ist jetzt angelegt, als nächstes muss darauf das ext4 Filesystem erstellt werden. Dazu benutzt Raspberry Pi OS das Kommando mkfs.ext4

Im Script sieht der Aufruf so aus:

echo "y" |mkfs.ext4 ${PARTITION}

Die Sicherheitsabfrage von mkfs.ext4 bestätigen wir über echo mit „y“. Die Variable ${PARTITION} wird das Script selber setzen.

Schritt 3: Partition einhängen

Die MicroSD Karte ist jetzt vorbereitet und wir hängen sie in den Mountpoint /mnt/speeddtest. Das Verzeichnis habe ich im Script fest kodiert und wird, falls es nicht existiert, automatisch angelegt.

#check if mount point is available, create otherwise
if [ ! -d "${MOUNTPOINT}" ]; then mkdir "${MOUNTPOINT}"; fi
mount -t ext4 "${PARTITION}" "${MOUNTPOINT}"

mount -t ext4 ${PARTITION} ${MOUNTPOINT} hängt die Partition (bei mir /dev/sda1) in den Mountpoint ein.

Schritt 4: Test vorbereiten

Auf der gemounteten Partition muss sysbench einige Dateien für den Test anlegen.

sysbench fileio --file-total-size=8G prepare > /dev/null

Die Ausgabe interessiert an dieser Stelle nicht, deshalb wird sie mit > /dev/null ins Null-Device gepiped.

Schritt 5: Test mit 16M Blockgröße

Jetzt kann der erste Testdurchlauf mit einer Blockgröße von 16M gestartet werden.

sysbench fileio --file-block-size=16K --file-total-size=8G --file-test-mode=rndrw --threads=$(nproc) run

Die Variable ${nproc} wird zu Beginn des Scripts definiert und gibt an, wie viele parallele Threads während des Tests benutzt werden sollen. Der Raspberry Pi hat vier Kerne, die nutzen wir auch voll aus. Im Realbetrieb greifen auch meist mehrere Prozesse gleichzeitig auf die Karte zu.

Schritt 6: Test mit 1M Blockgröße

Im zweiten Testdurchgang erhöhen wir die Blockgröße auf 1M.

sysbench fileio --file-block-size=1M --file-total-size=8G --file-test-mode=rndrw --threads=$(nproc) run

Schritt 7: Aufräumarbeiten

Nach Beendigung des Test räumt unser Script noch ein wenig auf.

sysbench fileio --file-total-size=8G cleanup
cd - >/dev/null
umount ${PARTITION}

sysbench löscht zunächst seine Dateien wieder ab. Mit cd – springen wir wieder in der Verzeichnis, von wo es gestartet wurde und mit umount ${PARTITION} wird die Partition auf der MicroSD Karte wieder ausgehängt.

Das komplette Script

Hier ist das komplette Script im Zusammenhang. Es ist nicht besonders spektakulär, da es keine großen Verzweigungen oder Schleifen hat.

#! /usr/bin/bash

MOUNTPOINT='/mnt/speedtest'

# number of threads used during testing
nproc=4

if [ "$EUID" -ne 0 ]
  then echo "Please run as root"
  exit 1
fi

if [ "${1}" ]; then
 DEVICE=${1}
 PARTITION=${DEVICE}1
 echo "using device ${DEVICE}"
else
 echo "using default device ${DEVICE}"
fi

# check if sd card is inserted
if [ -e ${DEVICE} ]; then
  echo "card inserted"
else
  echo "no sd card found"
  exit 2
fi

echo "deleting partition #1"
sfdisk --delete -w ${DEVICE} 1 && sync

echo "creating new ext4 partition"
echo ",," |sfdisk ${DEVICE} && sync

echo "creating ext4 filesystem on ${PARTITION}"
echo "y" |mkfs.ext4 ${PARTITION}

#check if mount point is available, create otherwise
if [ ! -d "${MOUNTPOINT}" ]; then mkdir "${MOUNTPOINT}"; fi
mount -t ext4 "${PARTITION}" "${MOUNTPOINT}"
cd "${MOUNTPOINT}"
echo "preparing tests"
sysbench fileio --file-total-size=8G prepare > /dev/null

# Test with 16K block size, random read/write
echo "run test with 16K block size"
sysbench fileio --file-block-size=16K --file-total-size=8G --file-test-mode=rndrw --threads=$(nproc) run

# Test with 1M  block size, random read/write
echo "run test with 1M block size"
sysbench fileio --file-block-size=1M --file-total-size=8G --file-test-mode=rndrw --threads=$(nproc) run

# cleanup the test files
echo "cleaning up test files"
sysbench fileio --file-total-size=8G cleanup
cd - >/dev/null
umount ${PARTITION}

Da ich das Script ursprünglich nur für mich selbst geschrieben habe, könnte ich für eine allgemeine Nutzung durchaus noch ein paar Sachen verbessern

  1. Mountpoint als Parameter übergeben.
  2. Sicherheitsabfrage vor dem Löschen der VFAT Partition.

Ich wollte es hier mal als praktisches Beispiel für die Nutzung von Parametern, Variablen und exit-Codes hinstellen. Du findest das Script auch im git-Repo.

Testlauf

Das fertige Script muss natürlich getestet werden. Dazu rufe ich es mit sudo /home/pi/bin/sdcardtester /dev/sda auf.

Der Pfad muss absolut eingegeben werden, da das bin Verzeichnis des Users pi nicht im PATH von root liegt. Vorsicht beim Testen, das angegebene Device wird gnadenlos überschrieben!

Nach dem Durchlauf sehen die letzten Ausgaben dann so aus:

Ausgabe des Testlaufs
Ausgabe des Testlaufs

Schreibe einen Kommentar

Creative Commons License
Except where otherwise noted, the content on this site is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
Olli Graf - raspithek.de
WordPress Cookie Hinweis von Real Cookie Banner