Startup Files

Einige der einfachsten Probleme in dessen Lösung man trotzdem Stunden investieren kann wenn man sich Skripte schreibt oder sich auf der Kommandozeile bewegt wird durch die Startup Files unter Linux verursacht. Man stelle sich zum Beispiel vor man schreibt ein Bash Skript in einem Terminal Emulator seiner Wahl und lässt das ganze hinterher per Cronjob laufen. Häufig passiert es dann, dass eine (Umgebungs-)Variable oder eine Funktion nicht ausgeführt werden kann weil es nicht gibt.


Die Lösung liegt hier meist in den Startup Files. Es gibt nämlich eine Reihe von Konfigurationsdateien die eingelesen werden wenn man einen Terminal Emulator oder ein virtuelles Terminal startet.

Terminal Emulator ? Virtuelles Terminal ? Bitte Was ? Ich dachte das heisst Kommandozeile oder Bash. Ja, in der Umgangssprache verwendet man häufig den Wortlaut “Mach mal gerade eine Terminal auf” oder “Starte mal ne Bash”. Genaunehmen spricht man dabei aber von einem Terminal Emulator Programm in einer Desktop Umgebung wie zum Beispiel gnome-terminal. Dieser Terminal Emulator startet dann eine Shell (Meist die Bash) und stellt uns die Kommandozeile bereit. Von virtuellen Terminals spricht man wenn die Tastenkombination STRG+ALT+F(x) gedrückt wurde, man die graphische Oberfläche verlässt und man durch das login Programm aufgefordert wird seinen Benutzernamen und das Passwort einzugegeben.

Mit diesem Hintergrundwissen kommen wir zurück zu den Startup Files. Davon gibt es nämlich mindestens vier mögliche.

  1. /etc/profile
  2. ~/.bash_profile
  3. ~/.bash_login
  4. ~/.profile

Die erste /etc/profile wird in jeden Fall immer eingelesen wenn eine Login-Shell gestartet wird. Von einer Login-Shell spricht man wenn man von dem Login Programm aufgefordert wird seinen Benutzernamen und Passwort einzugeben (also auch SSH). Zusätzlich wird nach einer existierenden Konfigurationsdatei im Homeverzeichnis (2-3) gesucht. Es gilt dabei das Motto “First Come, First Serve”. D.h. gibt es die Datei ~/.bash_profile wird diese benutzt und die anderen werden ignoriert. Gibt es keine ~/.bash_profile aber eine ~/.bash_login wird diese benutzt und die anderen ignoriert usw. Die Auswertungshierarchie entspricht dabei der wie ich sie hier aufgelistet habe. Man findet diese aber unter dem Begriff “Startup Files” in der manual der Bash, dazu einfach in der Bash

man bash

eintippen. Zusätzlich gibt es noch die ~/.bash_logout welche beim beenden der Bash eingelesen wird.

Und was ist wenn ich keine Login-Shell habe – Also einfach einen Terminal Emulator starte ? Hervorragende Frage! Dafür gibt es die häufig bekannte ~/.bashrc. Diese wird immer dann eingelesen wenn keine Login Shell gestartet wird.
Da es für die meisten Benutzer irritierend ist wenn man bei der Login-Shell und einem Terminal Emulator unterschiedliches Verhalten hat haben die meisten Distributionen eine in der ~/.profile die so oder so ähnlich aussieht:

if [ -n "$BASH_VERSION" ]; then
    # include .bashrc if it exists
    if [ -f "$HOME/.bashrc" ]; then
        . "$HOME/.bashrc"
    fi
fi

Diese Zeile überprüft ob es die .bashrc gibt und und liest sie auch bei einer Login-Shell ein. So hat man egal wann und wo man eine Bash startet eine gleiche Umgebung.

Zurück zum ursprünglichen Problem lässt sich jetzt erahnen warum eine Shell Skript sich bei der Ausführung per Cronjob nicht so verhält wie man es erwartet. Häufig hat man nämlich eine Zeile wie diese in der Crondatei stehen:

* 30 * * * * /home/kofrezo/bin/tolles-skript &> /dev/null

Im Skript selber hat man die Shebang Zeile #!/bin/sh stehen und startet damit die Shell die unter /bin/sh hinterlegt ist welche unter Ubuntu zum Beispiel die Dash ist. Abhilfe schafft es hier entweder die Shell für die Cronjobs neu zu setzten oder die Shebang Zeile auf #!/bin/bash anzupassen. Sollte es dennoch zu Problemen kommen hilft es häufig einen Blick in die Konfigurationsdateien der Cron Software (Zum Beispiel Anacron) zu werfen, da diese mitunter Standard Einstellungen überschreiben oder Shell Kommandos besonders behandeln.