Modul: Unix-basierte Betriebssysteme
Thema: Shell-Programmierung, POSIX-Konformität & Robustheit
Datei: file-tree.sh
Ziel der Aufgabe war die Entwicklung eines Shell-Skripts, das die Verzeichnisstruktur rekursiv auflistet (ähnlich dem Kommando tree). Dabei galten folgende strikte Restriktionen und Anforderungen:
ls, find, grep oder sed durften nicht verwendet werden. Die Lösung musste sich ausschließlich auf Shell-Builtins stützen.-a unterstützen, um versteckte Dateien (Dotfiles) anzuzeigen.Um die Aufgabe ohne externe Binaries zu lösen, wurden folgende Konzepte angewendet:
ls): Die Shell expandiert das Muster * zu einer Liste von Dateinamen. Um die Option -a zu implementieren, wird das Shell-Builtin shopt -s dotglob genutzt, welches versteckte Dateien für das Wildcard sichtbar macht.find):walk_tree ruft sich selbst auf, sobald sie auf ein Unterverzeichnis stößt. Ein Parameter prefix sorgt für die korrekte visuelle Einrückung.${variable##pattern} verwendet, was performanter ist als externe Tools wie basename.stderr ausgegeben. Endlosschleifen durch Symlinks werden mittels [ -L ] verhindert.Der folgende Code (file-tree.sh) enthält die vollständige Logik inklusive Fehlerbehandlung und Kommentaren.
#!/bin/bash
# =============================================================================
# SKRIPT: file-tree.sh
# ZWECK: Rekursive Verzeichnisauflistung (Tree) NUR mit Shell-Builtins
# AUTHOR: [Dein Name]
# =============================================================================
# 'set -u': Abbruch bei uninitialisierten Variablen (Vermeidung von Tippfehlern)
set -u
# Standard: Keine versteckten Dateien anzeigen
SHOW_HIDDEN=0
# 1. Argumente parsen (getopts - siehe PDF Kap 3.5)
while getopts "a" opt; do
case $opt in
a)
SHOW_HIDDEN=1
;;
\?)
echo "Fehler: Unbekannte Option. Nutzung: $0 [-a] [Verzeichnis]" >&2
exit 1
;;
esac
done
shift $((OPTIND-1))
# Startverzeichnis festlegen (Default: aktuelles Verzeichnis ".")
START_DIR="${1:-.}"
# 2. Validierung vor Start (Robustheit)
if [ ! -e "$START_DIR" ]; then
echo "Fehler: Ziel '$START_DIR' existiert nicht." >&2
exit 1
fi
if [ ! -d "$START_DIR" ]; then
echo "Fehler: '$START_DIR' ist kein Verzeichnis." >&2
exit 1
fi
if [ ! -r "$START_DIR" ]; then
echo "Fehler: Keine Leserechte für '$START_DIR'." >&2
exit 1
fi
# 3. Rekursive Funktion: walk_tree
walk_tree() {
local current_dir="$1"
local prefix="$2"
# Shell-Optionen für Globbing anpassen
shopt -s nullglob
# 'dotglob': Steuert Sichtbarkeit von versteckten Dateien (.datei)
if [ "$SHOW_HIDDEN" -eq 1 ]; then
shopt -s dotglob
else
shopt -u dotglob
fi
# Iteration über alle Einträge im Verzeichnis
for entry in "$current_dir"/*; do
# Dateinamen extrahieren mittels Parameter Expansion
local basename="${entry##*/}"
# Sicherheitscheck: Navigationselemente . und .. überspringen
if [ "$basename" = "." ] || [ "$basename" = ".." ]; then
continue
fi
# ROBUSTHEIT: Symlinks behandeln (Vermeidung von Zyklen)
if [ -L "$entry" ]; then
echo "${prefix}${basename} -> (Symlink)"
continue
fi
# Unterscheidung Verzeichnis vs. Datei
if [ -d "$entry" ]; then
# ROBUSTHEIT: Prüfen ob Unterverzeichnis lesbar ist
if [ -r "$entry" ]; then
echo "${prefix}${basename}/"
# REKURSION: Selbstaufruf mit erweitertem Prefix
walk_tree "$entry" "$prefix "
else
echo "Warnung: Kein Zugriff auf '$basename'" >&2
echo "${prefix}${basename}/ [ZUGRIFF VERWEIGERT]"
fi
else
# Ausgabe Datei
echo "${prefix}${basename}"
fi
done
# Aufräumen der Shell-Optionen
shopt -u nullglob
shopt -u dotglob
}
# 4. Hauptprogramm
echo "${START_DIR}/"
walk_tree "$START_DIR" " "
exit 0
Your content here