Die Kommandozeile automatisieren
Ausführen: Skript als skript.sh speichern, ausführbar machen (chmod +x skript.sh) und mit ./skript.sh starten oder per bash skript.sh.
#!/usr/bin/env bash; trennt, && (bei Erfolg), || (bei Fehler), & (Hintergrund)0 = Erfolg, in $?--help, man, typechmod +xecho "Hallo Welt"
pwd >/dev/null && echo "pwd gibt das aktuelle Verzeichnis aus"
echo "Ergebnis: $((6 * 7))"
printf "%s ist %d Jahre alt\n" "Mia" 17var=wert ohne Leerzeichen, lesen mit "$var", ${var}$(befehl) übernimmt die Ausgabe; $((rechnung)) rechnet'...' wörtlich, "..." mit Ersetzung*, ?, [a-z]; Klammern {a,b} und {1..5}export macht Variablen für Kindprozesse sichtbarname="Mia"
alter=17
echo "Name: $name, Alter: $alter"
echo "Nächstes Jahr: $((alter + 1))"
echo "${name}s Hund" # {} trennt den Namen vom Text
echo "Länge: ${#name}"
unset name
echo "Nach unset: [${name}]"
readonly PI=3.14
echo "$PI"if wertet den Exit-Status eines Befehls aus[[ ... ]] für Tests (Text, Zahlen, Dateien), (( ... )) zum Rechnen-eq -lt -gt, Text mit == !=, Muster mit == und =~-f -d -e -r -w -x -scase für Mustervergleiche; ${var:-standard} für Standardwertezahl=7
if [[ $zahl -gt 10 ]]; then
echo "groß"
elif [[ $zahl -gt 5 ]]; then
echo "mittel"
else
echo "klein"
fi
if grep -q "bash" <<< "ich lerne bash"; then
echo "gefunden"
fi
if ! command -v gibtsnicht >/dev/null; then
echo "Programm fehlt"
fifor x in liste; do ... done, Bereiche {1..10}, C-Stil ((i=0;i<n;i++))*.txt), nicht per $(ls)while/until mit Bedingung; while IFS= read -r zeile; do ... done < dateiwhile läuft in einer Unter-Shell: Prozess-Ersetzung < <(...) nutzenbreak und continue (auch mit Ebenenzahl)for farbe in rot grün blau; do
echo "Farbe: $farbe"
done
for i in {1..5}; do printf "%d " "$i"; done; echo
for i in {10..0..5}; do printf "%d " "$i"; done; echo
for ((i = 0; i < 3; i++)); do echo "Zähler $i"; done # C-Stil
summe=0
for n in 1 2 3 4; do summe=$((summe + n)); done
echo "Summe: $summe"$1, $#, "$@", shift; Optionen mit getoptsname() { ... }, local für lokale Variablenreturn liefert den Status (0 bis 255), Werte per echo und $(...)source lädt eine Bibliothek"$@" statt $*set -- "erstes Argument" zweites drittes
echo "Anzahl: $#"
echo "1: $1 | 2: $2"
for a in "$@"; do echo " [$a]"; done
shift
echo "Nach shift: $1 (Anzahl $#)"
printf "[%s]" "$*"; echoa=(x y), ${a[@]}, ${#a[@]}, "${a[@]}" zum Durchlaufendeclare -A m, ${m[key]}, ${!m[@]}${s:0:3}, ${s/a/b}, ${s^^}, ${s##*/}, ${s%.*}IFS steuert das Zerlegen (read -ra)fruechte=(Apfel Birne "rote Kirsche")
echo "${fruechte[0]} | ${fruechte[2]}"
echo "Anzahl: ${#fruechte[@]}"
fruechte+=(Dattel) # anhängen
fruechte[1]="Banane" # ändern
echo "Alle: ${fruechte[@]}"
echo "Indizes: ${!fruechte[@]}"
echo "Ab Index 1: ${fruechte[@]:1}"
echo "Zwei ab 1: ${fruechte[@]:1:2}"
unset 'fruechte[0]'
echo "Nach unset: ${fruechte[@]} (${#fruechte[@]})"
for f in "${fruechte[@]}"; do echo "- $f"; done # Anführungszeichen wichtig!
zahlen=(5 3 9 1)
sortiert=($(printf "%s\n" "${zahlen[@]}" | sort -n))
echo "Sortiert: ${sortiert[*]}"> überschreibt, >> hängt an, < liest, 2> leitet Fehler um, 2>&1 führt zusammen| verbindet Programme; set -o pipefail meldet Fehler in der Pipe<<EOF, Here-String <<<tee, xargs, <(...) erweitern die Möglichkeiten& startet im Hintergrund, wait wartetcd "$(mktemp -d)"
echo "Zeile 1" > datei.txt # überschreiben
echo "Zeile 2" >> datei.txt # anhängen
cat datei.txt
wc -l < datei.txt # Datei als Eingabe
ls /gibt/es/nicht 2> fehler.txt # nur Fehler in Datei
echo "Fehler gespeichert: $(wc -l < fehler.txt) Zeile(n)"
ls /gibt/es/nicht 2>/dev/null # Fehler wegwerfen
echo "stdout" > alles.txt 2>&1 # beide in dieselbe Datei
ls /gibt/es/nicht >> alles.txt 2>&1
wc -l < alles.txt
echo "nur Fehlerausgabe" >&2 # stdout nach stderr umleitengrep sucht (-i -v -n -c -E -o -r), sed ersetzt (s/a/b/g), awk rechnet mit Spaltencut, sort, uniq -c, tr, wc, head, tail, paste als Bausteinefind ... -exec / xargs wenden Befehle auf Dateien ancat > log.txt <<'EOF'
2025-03-01 INFO Server gestartet
2025-03-01 ERROR Datenbank nicht erreichbar
2025-03-02 INFO Nutzer mia angemeldet
2025-03-02 WARN Speicher knapp
2025-03-03 ERROR Zeitüberschreitung bei /api/data
2025-03-03 INFO Nutzer tom angemeldet
EOF
wc -l log.txt
head -n 2 log.txt
tail -n 1 log.txtpwd, cd, ls, mkdir -p; absolute und relative Pfadecp -r, mv, rm -r (gefährlich!), ln -s, touchrwx für Besitzer/Gruppe/andere; chmod 755, chmod u+x, chownhead, tail, less, stat, file, diff zum Ansehentar -czf / -xzf für Archivecd "$(mktemp -d)"
mkdir projekt
cd projekt
pwd | sed "s|.*/||" # nur der Ordnername
mkdir -p a/b/c # verschachtelt anlegen
touch a/datei1 a/b/datei2
ls
ls -R | head -8
cd a/b
cd ../.. # zwei Ebenen hoch
cd - >/dev/null # zurück zum vorigen Ordner (cd - gibt den Pfad aus)
basename "$PWD"
cd ~ && [[ $PWD == "$HOME" ]] && echo "zu Hause"#!/usr/bin/env bash und set -euo pipefailstderr (>&2), sinnvolle Exit-Codestrap ... EXIT räumt zuverlässig auf-- vor Dateinamenshellcheck, bash -n und set -x helfen beim Debuggen#!/usr/bin/env bash
set -euo pipefailps, top, kill, pkill, $!, wait, timeouttrap fängt Signale abcron: fünf Zeitfelder, absolute Pfade, Ausgabe loggenscp/rsync für Dateienapt, dnf, brew) und systemctl für Diensteps aux # alle Prozesse
ps aux | grep nginx # bestimmte suchen
pgrep -a python # PIDs nach Namen
top / htop # Live-Ansicht (q beendet)
kill 1234 # sanft beenden (SIGTERM)
kill -9 1234 # erzwingen (SIGKILL), nur wenn nötig
pkill -f meinskript # nach Namen beenden
nohup ./lang.sh & # läuft nach dem Logout weiterset -euo pipefail
backup() {
local quelle=$1 ziel=$2 behalten=${3:-3}
mkdir -p "$ziel"
local name
name="backup-$(basename "$quelle")-$4.tar.gz"
tar -czf "$ziel/$name" -C "$(dirname "$quelle")" "$(basename "$quelle")"
# alte Sicherungen löschen: nach Namen sortieren, nur die neuesten $behalten behalten
ls -1 "$ziel" | sort | head -n -"$behalten" | while read -r alt; do
rm -- "$ziel/$alt"
echo "gelöscht: $alt"
done
echo "erstellt: $name"
}
arbeit=$(mktemp -d)
mkdir "$arbeit/daten"
echo "wichtig" > "$arbeit/daten/a.txt"
for tag in 01 02 03 04 05; do
backup "$arbeit/daten" "$arbeit/sicherungen" 3 "2025-03-$tag"
done
echo "Übrig:"
ls "$arbeit/sicherungen"set -euo pipefail, lass ShellCheck prüfen#!/usr/bin/env bash
set -euo pipefail
trap 'rm -rf "$tmp"' EXIT
tmp=$(mktemp -d)
main() {
local name=${1:-Welt}
echo "Hallo, $name"
}
main "$@"