Variablen und Umgebung
Zwei Arten von Variablen
Abschnitt betitelt „Zwei Arten von Variablen“Eine Variable setzt du in der Bash mit name=wert, ohne Leerzeichen um das Gleichheitszeichen, und liest sie mit $name. Es gibt aber zwei Sorten, und der Unterschied erklärt viele Rätsel:
- Shell-Variablen gehören nur der laufenden Shell. Programme, die du startest, wissen nichts davon.
- Umgebungsvariablen (environment variables) werden an jedes Programm vererbt, das die Shell startet. Dazu gehören
HOME,PATH,LANG,USER.
Aus einer Shell-Variable wird mit export eine Umgebungsvariable:
flowchart TD
S["Deine Bash<br/>farbe=blau (Shell-Variable)<br/>export EDITOR=vim (Umgebung)"]
S -->|startet| P1["Programm, z.B. git<br/>sieht EDITOR, aber nicht farbe"]
S -->|startet| P2["Skript ./test.sh<br/>sieht EDITOR, aber nicht farbe"]
Hands-on: Eine zweite Bash als Kindprozess ist der einfachste Test.
farbe=blauecho "$farbe"bash -c 'echo "Kind sieht: $farbe"'export farbebash -c 'echo "Kind sieht: $farbe"'export EDITOR=vimenv | grep -E '^(farbe|EDITOR)='Was erwartest du? Beim ersten Kindprozess ist die Ausgabe leer, nach export steht blau da. env und printenv listen alle Umgebungsvariablen, printenv HOME eine einzelne. Eine Variable nur für einen einzigen Aufruf setzt du vor den Befehl: LANG=C date gibt das Datum auf Englisch aus, ohne deine Shell zu ändern.
Konvention: Umgebungsvariablen schreibt man gross (PATH), eigene Shell-Variablen in Skripten klein (anzahl). So kollidieren sie nicht.
Die wichtigsten vorgegebenen Variablen
Abschnitt betitelt „Die wichtigsten vorgegebenen Variablen“| Variable | Inhalt |
|---|---|
HOME |
Dein Home-Verzeichnis, dasselbe wie ~ |
USER |
Dein Benutzername |
PATH |
Suchpfad für Befehle |
PWD |
Aktuelles Verzeichnis, wie pwd |
SHELL |
Deine Login-Shell |
LANG |
Sprache und Zeichensatz, etwa de_CH.UTF-8 |
EDITOR |
Editor, den git, crontab -e und andere aufrufen |
PS1 |
Aussehen des Prompts |
HISTSIZE |
Anzahl Befehle, die history behält |
$? |
Exit-Status des letzten Befehls (keine Umgebungsvariable) |
$$ |
Prozess-ID der Shell |
Wo die Shell ihre Einstellungen liest
Abschnitt betitelt „Wo die Shell ihre Einstellungen liest“Variablen, die du im Terminal setzt, sind beim nächsten Login weg. Damit Einstellungen bleiben, trägst du sie in eine Startdatei ein. Welche die Bash liest, hängt davon ab, wie sie gestartet wurde:
| Datei | Gelesen von | Typischer Inhalt |
|---|---|---|
/etc/profile |
Login-Shells, systemweit | PATH für alle, umask |
~/.profile |
Login-Shells, persönlich | Umgebungsvariablen, ~/bin in den PATH |
/etc/bash.bashrc |
interaktiven Shells, systemweit | Prompt, Vervollständigung |
~/.bashrc |
interaktiven Shells, persönlich | Aliase, Funktionen, Prompt, History |
~/.bash_aliases |
von Ubuntus ~/.bashrc eingebunden |
deine Aliase und Funktionen |
Eine Login-Shell entsteht bei der Anmeldung an der Konsole oder per SSH. Eine interaktive Shell ist jedes Terminalfenster, das du danach öffnest. Auf Ubuntu musst du dich darum nicht kümmern: ~/.profile lädt am Ende ~/.bashrc, und ~/.bashrc lädt ~/.bash_aliases, falls die Datei existiert. Praktische Regel:
- Umgebungsvariablen wie
EDITORoder PATH-Ergänzungen nach~/.profile. - Alles andere (Aliase, Funktionen, Prompt) nach
~/.bash_aliases.
~/.bashrc enthält bereits einen Block, der ~/.bash_aliases einliest. ~/.profile fügt ~/bin und ~/.local/bin zum PATH hinzu, wenn sie beim Login existieren.
Statt ~/.profile gibt es ~/.bash_profile, das ~/.bashrc lädt. Eine ~/.bash_aliases wird nicht automatisch eingebunden, trage die Zeile . ~/.bash_aliases selbst in ~/.bashrc ein.
source: eine Datei in der laufenden Shell ausführen
Abschnitt betitelt „source: eine Datei in der laufenden Shell ausführen“Nach einer Änderung an ~/.bash_aliases willst du nicht jedes Mal ein neues Terminal öffnen. source datei (oder kurz . datei) führt die Datei in der aktuellen Shell aus. Würdest du sie wie ein Skript mit bash datei starten, liefe sie in einem Kindprozess und alle Definitionen wären danach wieder weg, aus demselben Grund, aus dem cd ein Builtin sein muss.
source ~/.bash_aliases. ~/.bash_aliasesEin Alias ist eine Abkürzung für einen längeren Befehl. Ubuntu bringt schon einige mit:
aliasalias ll='ls -alF'alias ..='cd ..'alias hist='history | grep -i'llhist mkdirunalias ..\lsalias ohne Argumente zeigt alle, unalias löscht einen. Der Backslash vor \ls umgeht den Alias einmalig und startet das echte Programm. Alles, was nach dem Alias auf der Zeile steht, wird angehängt, darum funktioniert hist mkdir. Ein paar Beispiele aus der Praxis:
# Sicherheitsnetz: nachfragen vor dem Überschreibenalias rm='rm -i'alias cp='cp -i'alias mv='mv -i'
# Kürzer tippenalias ll='ls -alF'alias la='ls -A'alias ..='cd ..'alias ...='cd ../..'
# Suchenalias hist='history | grep -i'alias fp='ps -ef | grep -v grep | grep -i'
# Manpages in einer bestimmten Sprachealias mande='LANG=de_CH.UTF-8 man'alias manen='LANG=en_US.UTF-8 man'Funktionen: Aliase mit Argumenten
Abschnitt betitelt „Funktionen: Aliase mit Argumenten“Ein Alias kann nur Text anhängen. Sobald ein Argument mitten im Befehl stehen soll, brauchst du eine Funktion. Innerhalb der Funktion heissen die Argumente $1, $2 und so weiter, "$@" sind alle zusammen.
alias manen='LANG=en_US.UTF-8 man'
# Verzeichnis anlegen und gleich hineinwechselnmkcd() { mkdir -p "$1" && cd "$1" || return}
# Datei mit Zeitstempel sichern: sichern config.txt -> config.txt.2026-11-05sichern() { cp -v "$1" "$1.$(date +%F)"}
# Manpage als PDF öffnen (braucht ghostscript)manpdf() { local pdf="/tmp/$1.pdf" man -t "$1" | ps2pdf - "$pdf" && xdg-open "$pdf"}
# Linux-Pendant zum open-Befehl von macOSopen() { for f in "$@"; do xdg-open "$f" &>/dev/null; done; }Beachte die Details, die du von der Seite Quoting kennst: "$1" in Anführungszeichen, $(...) für die Substitution, local für Variablen, die nur in der Funktion gelten. Das || return nach cd ist eine ShellCheck-Empfehlung: Schlägt cd fehl, bricht die Funktion ab, statt im falschen Verzeichnis weiterzumachen.
Hands-on: Definiere mkcd direkt im Terminal und probiere sie aus.
mkcd() { mkdir -p "$1" && cd "$1" || return; }mkcd /tmp/neu/tief/drinpwdtype mkcdcd ~type meldet, dass mkcd eine Funktion ist, und zeigt sogar ihren Code.
Prompt und History
Abschnitt betitelt „Prompt und History“Der Prompt steht in PS1. Ubuntus Standard ist etwa \u@\h:\w\$ , also Benutzer, Host, Verzeichnis. Zum Ausprobieren:
echo "$PS1"PS1='[\t] \w \$ 'PS1='\u@\h:\w\$ 'Die Platzhalter sind in man bash unter «PROMPTING» aufgelistet. Für die History sind drei Variablen interessant:
HISTSIZE=50000 # Zeilen im SpeicherHISTFILESIZE=100000 # Zeilen in ~/.bash_historyHISTCONTROL=ignoredups # gleiche Befehle nacheinander nur einmalEigene Skripte im PATH
Abschnitt betitelt „Eigene Skripte im PATH“Dein Verzeichnis ~/bin wird von ~/.profile beim Login in den PATH aufgenommen, sofern es existiert. Möchtest du ein weiteres Verzeichnis ergänzen, gehört die Zeile ebenfalls in ~/.profile:
PATH="$HOME/werkzeuge:$PATH"Schreibe $HOME, nicht ~: Innerhalb der Anführungszeichen wird die Tilde nicht ersetzt, und die Shell würde ein Verzeichnis namens ~ suchen.
Lösung anzeigen
# shellcheck shell=bash## Persönliche Aliase und Funktionen, wird von ~/.bashrc geladen
# Vor dem Überschreiben oder Löschen nachfragenalias rm='rm -i'alias cp='cp -i'
# Ausführliche Liste mit versteckten Dateienalias ll='ls -alF'
# Ein Verzeichnis nach obenalias ..='cd ..'
# History durchsuchen, Gross-/Kleinschreibung egalalias hist='history | grep -i'
# Verzeichnis anlegen und hineinwechselnmkcd() { mkdir -p "$1" && cd "$1" || return}
# Datei mit Datum im Namen sichernsichern() { local ziel ziel="$1.$(date +%F)" cp -v "$1" "$ziel"}
# Längere History, Duplikate nicht doppelt speichernHISTSIZE=50000HISTFILESIZE=100000HISTCONTROL=ignoredupssource ~/.bash_aliasesaliastype mkcd sichernmkcd /tmp/aliastest && pwdcp ~/.bash_aliases labs/linux/07-shell/bash_aliasesshellcheck labs/linux/07-shell/bash_aliasesSelbstcheck · 5 Fragen
Weiterführend
Abschnitt betitelt „Weiterführend“man bash, Abschnitte «INVOCATION», «ALIASES», «FUNCTIONS» und «PROMPTING»- Bash Reference Manual: Bash Startup Files
- ubuntuusers Wiki: Bash/Alias