Kurz: main() { local name={1:-Welt} echo "Hallo, name” } main ”$@” ```
Teil des Kurses Bash
Skript-Grundgerüst
#!/usr/bin/env bash
set -euo pipefail
trap 'rm -rf "$tmp"' EXIT
tmp=$(mktemp -d)
main() {
local name=${1:-Welt}
echo "Hallo, $name"
}
main "$@"Variablen und Erweiterungen
| Syntax | Bedeutung |
|---|---|
var=wert | Zuweisung (ohne Leerzeichen) |
"$var" / "${var}" | Wert lesen (immer quoten) |
$(befehl) | Ausgabe des Befehls |
$((a + b)) | Rechnen |
${var:-x} / ${var:=x} / ${var:?msg} | Standardwert / zuweisen / Fehler |
${#var} | Länge |
${var:2:3} | Teilstring |
${var/a/b} / ${var//a/b} | ersetzen |
${var#*/} / ${var##*/} | Präfix kürzen |
${var%.*} / ${var%%.*} | Suffix kürzen |
${var^^} / ${var,,} | groß / klein |
Spezielle Variablen
$0 Skriptname, $1..$9 Argumente, $# Anzahl, "$@" alle Argumente, $? Exit-Status, $$ eigene PID, $! letzte Hintergrund-PID, $RANDOM, $LINENO, $PWD, $HOME, $PATH, $IFS.
Tests
| Zahlen | Text | Dateien |
|---|---|---|
-eq -ne -lt -le -gt -ge | == != < > -z -n =~ | -e -f -d -r -w -x -s -L |
Verknüpfen: &&, ||, !. Rechnen: (( a > b )).
Kontrollstrukturen
if cmd; then ...; elif ...; else ...; fi
case "$x" in a|b) ...;; *) ...;; esac
for i in {1..10}; do ...; done for ((i=0;i<n;i++)); do ...; done
while cond; do ...; done until cond; do ...; done
while IFS= read -r z; do ...; done < datei
break continue return exit NArrays
a=(x y z) a+=(w) ${a[0]} "${a[@]}" ${#a[@]} ${!a[@]} unset 'a[1]'
declare -A m; m[key]=wert; ${m[key]}; "${!m[@]}"; [[ -v m[key] ]]Umleitung
> f / >> f | stdout überschreiben / anhängen |
2> f / 2>&1 / &> f | stderr / zusammen / alles |
< f / <<EOF / <<< "text" | Eingabe aus Datei / Here-Doc / Here-String |
cmd1 | cmd2 | Pipe |
<(cmd) | Ausgabe als temporäre Datei |
Wichtige Befehle
| Zweck | Befehle |
|---|---|
| Dateien | ls cd pwd cp mv rm mkdir rmdir touch ln find stat file du df |
| Ansehen | cat less head tail wc diff sort uniq |
| Text | grep sed awk cut tr paste tee xargs rev tac nl |
| Rechte | chmod chown umask sudo |
| Archive | tar gzip gunzip zip unzip |
| Prozesse | ps top kill pkill nohup wait sleep timeout |
| Netz | curl wget ssh scp rsync ping dig ss |
| System | uname whoami id date uptime free env |
Häufige Fehler
| Problem | Ursache / Lösung |
|---|---|
command not found bei x = 1 | Leerzeichen um =: x=1 |
| Dateinamen mit Leerzeichen zerbrechen | Variablen quoten: "$datei" |
[: too many arguments | [[ ]] verwenden und quoten |
for f in $(ls) | stattdessen for f in * |
| Variable nach Pipe-Schleife leer | Unter-Shell: < <(cmd) statt cmd | |
| Skript läuft trotz Fehler weiter | set -euo pipefail |
Permission denied | chmod +x, Pfad ./skript.sh |
CRLF-Zeilenenden (^M) | dos2unix oder sed -i 's/\r$//' |
Weiterlernen
man bash, Handbuch unter gnu.org/software/bash/manual- ShellCheck (shellcheck.net) zeigt Fehler und Verbesserungen
- Übungen: Bash Scripting auf Exercism, OverTheWire “Bandit”
- Wiki dieser Seite: Artikel zu Linux, SSH und Cron
Merke
- Quote Variablen, nutze
set -euo pipefail, lass ShellCheck prüfen - Kleine Programme per Pipe kombinieren
- Für Struktur und Daten ab einer gewissen Größe Python wählen
Quiz zur Selbstkontrolle
Welche Zeile gehört in den Kopf robuster Skripte?
- set -euo pipefail (richtig)
- set +e
- set -x -v
- export ALL
Wie schützt du dich vor Leerzeichen in Dateinamen?
- Variablen in Anführungszeichen setzen (richtig)
- Leerzeichen entfernen
- Nur Kleinschreibung nutzen
- Dateien nicht benennen
Welches Werkzeug findet typische Skriptfehler automatisch?
- ShellCheck (richtig)
- gcc
- make
- sudo
Weiter im Kurs
Zurück: Projekte: Skripte aus der Praxis
Alle Kapitel: Bash im Überblick