EMZETT.
Login

Kurz: Zuweisung ohne Leerzeichen um das =, Lesen mit $:

Teil des Kurses Bash

Kapitel 2 von 13 im Kurs Bash. Mit Fortschritt, Quiz und Zertifikat auf der Lernseite.

Variablen

Zuweisung ohne Leerzeichen um das =, Lesen mit $:

name="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"

Ausgabe:

Name: Mia, Alter: 17
Nächstes Jahr: 18
Mias Hund
Länge: 3
Nach unset: []
3.14

Achtung

name = "Mia" (mit Leerzeichen) versucht, ein Programm name zu starten. Und: Variablen in Bash sind standardmäßig Text; Rechnen geht mit $(( )).

Befehlsersetzung

Mit $(befehl) landet die Ausgabe eines Befehls in einer Variable oder einem String:

dateien=$(printf "a\nb\nc\n" | wc -l)
echo "Zeilen: $dateien"
heute_jahr=$(date -d 2025-03-15 +%Y)
echo "Jahr: $heute_jahr"
echo "Länge von 'Hallo': $(echo -n Hallo | wc -c)"
echo "Verschachtelt: $(echo $(echo tief))"

Ausgabe:

Zeilen: 3
Jahr: 2025
Länge von 'Hallo': 5
Verschachtelt: tief

Quoting: der wichtigste Stolperstein

SchreibweiseWirkung
"text $var"Variablen und $(...) werden ersetzt, Leerzeichen bleiben erhalten
'text $var'alles wörtlich, nichts wird ersetzt
\$ \" \\einzelnes Zeichen entschärfen
ohne AnführungszeichenWort-Trennung und Mustererweiterung (Globbing) passieren!
datei="mein Bericht.txt"
printf "[%s]\n" $datei             # ohne Quotes: zwei Wörter!
printf "[%s]\n" "$datei"           # mit Quotes: ein Wort
echo 'Kein $Ersatz: $(date)'
echo "Dollar: \$5, Anführung: \" und Backslash: \\"
echo "Tab:\tText" 'und $'"'\t'"'Tab'

Ausgabe:

[mein]
[Bericht.txt]
[mein Bericht.txt]
Kein $Ersatz: $(date)
Dollar: $5, Anführung: " und Backslash: \
Tab:\tText und $'\t'Tab

Regel: Setze Variablen immer in doppelte Anführungszeichen ("$var"), außer du willst bewusst aufteilen.

Globbing: Muster für Dateinamen

cd "$(mktemp -d)"
touch a.txt b.txt c.md d1 d2 d10 .versteckt
echo *            # alle (ohne versteckte)
echo *.txt
echo d?
echo d[0-9]*
echo {a,b}.txt    # Klammererweiterung, kein Glob
echo {1..5} {a..c}
echo *.xyz        # kein Treffer: Muster bleibt stehen

Ausgabe:

a.txt b.txt c.md d1 d10 d2
a.txt b.txt
d1 d2
d1 d10 d2
a.txt b.txt
1 2 3 4 5 a b c
*.xyz

Umgebungsvariablen

Normale Variablen gelten nur in der aktuellen Shell. Mit export erben sie auch gestartete Programme:

lokal="nur hier"
export GETEILT="auch in Kindern"
bash -c 'echo "lokal=[$lokal] geteilt=[$GETEILT]"'
echo "HOME beginnt mit /: ${HOME:0:1}"
echo "Shell-Variable: $0 | Argumente: $#"
VAR=temporaer bash -c 'echo "nur für diesen Aufruf: $VAR"'
echo "danach: [${VAR:-leer}]"

Ausgabe:

lokal=[] geteilt=[auch in Kindern]
HOME beginnt mit /: /
Shell-Variable: main.sh | Argumente: 0
nur für diesen Aufruf: temporaer
danach: [leer]

Wichtige Variablen: HOME, PATH (Suchpfad für Programme), PWD, USER, SHELL, RANDOM, $? (Exit-Status), $$ (Prozess-ID), $! (letzter Hintergrundprozess).

Eingabe lesen

read -r zeile <<< "Mia 17 Berlin"
echo "Zeile: $zeile"
read -r name alter ort <<< "Mia 17 Berlin"
echo "$name ist $alter und wohnt in $ort"
IFS=: read -r user pw uid rest <<< "root:x:0:0:Admin"
echo "$user hat UID $uid"
# Interaktiv: read -rp "Name? " name

Ausgabe:

Zeile: Mia 17 Berlin
Mia ist 17 und wohnt in Berlin
root hat UID 0

Merke

  • var=wert ohne Leerzeichen, lesen mit "$var", ${var}
  • $(befehl) übernimmt die Ausgabe; $((rechnung)) rechnet
  • Immer Variablen in doppelte Anführungszeichen setzen
  • '...' wörtlich, "..." mit Ersetzung
  • Globbing: *, ?, [a-z]; Klammern {a,b} und {1..5}
  • export macht Variablen für Kindprozesse sichtbar

Übungsaufgabe

Lege in einem temporären Ordner Dateien mit Leerzeichen im Namen an und gib sie mit for korrekt gequotet aus.

Quiz zur Selbstkontrolle

Weiter im Kurs

Zurück: Einführung und erstes Skript

Weiter: Bedingungen und Tests

Alle Kapitel: Bash im Überblick