Shells? Und wenn ja, wieviele?
Es gibt unzählige Shells in der Unix/Linux Welt. Welche davon in einer Distri verfügbar sind, kann man sich oft mit cat /etc/shells angucken. Diese Liste ist nur ein sehr kleiner Ausschnitt der unzähligen Shells und es ist nicht klar, ob manche davon erst zu installieren sind. Ganz sicher werden NICHT alle gelistet die es gibt.
(Es gäbe vogelwilde Kommandos, um herauszufinden, welche installiert sind, aber so viel wollen wir gar nicht wissen...).
Die Standardshell bei openSUSE ist jedenfalls die bash, wie bei den allermeisten Distris.
Mit chsh kann man sich als User eine andere Shell zuordnen, wenn sie denn lauffähig installiert ist. chsh erlaubt es einem User die eigene Zeile in der /etc/passwd zu ändern, ohne Root-Rechte haben zu müssen.
Die meisten Shells sind dazu da, entweder Eingaben des Users auszuführen, oder stattdessen Scripte aufzurufen. Manche shells, wie z.B. /sbin/nologin sind spezialisiert auf nur einen Job. Trägt man in eine Userzeile im Shellfeld /sbin/nologin ein (siehe man 5 passwd ), so kann sich dieser User nicht mehr am System anmelden, und wird höflich darüber informiert. (erstellt man dazu noch die optionale Datei /etc/nologin.txt, so wird dieser Text dem User auch noch vor die Nase gehalten.). Auch von diesen spezialisierten Shells gibt es einige. Und viele Programme bringen noch ihre eigene Shell mit. Sogar zypper sh ist eine interaktive Shell, innerhalb derer man alle zypper- Kommandos ausführen kann. Sehr nützlich, wenn man mal seine Paket und Repolisten bereinigen möchte.
Ich schreibe im Weiteren NUR über die bash, auch wenn viele Shells ganz ähnlich, und oft sogar gleich, arbeiten, so gibt es stellenweise doch subtile bis hin zu sehr drastischen Unterschieden.
Der Name Shell ist das englische Wort für Muschel. Wie eine Muschel legt sich die Shell, unser Kommandointerpreter, um alles, was der Kernel zur Verfügung stellt und macht Dienste und Programme dem User einfach bedienbar. Also relativ einfach. Die erste Shell gab es schon 1965, und viele Shells wurden anfangs der 70er geboren und werden seit dieser Zeit konstant weiterentwickelt.
Und was hat nun su und sudo damit zu schaffen?
Weil ein Linux nun mal von Haus aus ein Multitasking und Multiuser System ist, sind diese Shells ziemlich komplex, da sie nicht nur Programme ausführen können. Dazu müssen sie alle Sicherheitsvorgaben beachten können und sich entsprechend verhalten können. Jeder User soll ja -egal wieviele Rechte er auf dem System hat- seine Jobs immer mit den dafür benötigten Rechten ausführen können, und möglichst auch kein Jota mehr als wirklich dafür benötigte Rechte.
Dazu wird für jedes Programm ein Prozess erzeugt, dem eine Umgebung (ein environment) zugordnet ist. Und noch Verwaltungsinformationen des Kernels. Die bestehen aus Rechten und Laufzeitinformationen. (Man kann einzelnen Prozessen geringere Proiorität einräumen, damit wichtige Prozesse ungestört ihren Job erledigen können, ohne von unwichtigen Prozessen unterbrochen zu werden. (siehe man nice).
Einige Envrionmentvariablen können vom User geändert werden, andere nicht. (Es gibt noch ein paar spezielle Variablen, die jeweils eine Sonderfunktion zur Verfügung stellen. So gibt ein echo $SECONDS die Anzahl der Sekunden aus, die seit dem Start dieser Shellinstanz vergangen sind, oder ein echo $RANDOM eine zufällige Integerzahl zwischen 0 und 32767.)
Der Befehl env hat zwei Aufgaben. Ohne Argument gibt er schlicht alle Umgebungsvariablen aus, die für den User relevant sind, aber nicht alle, die existieren. Einige sind so fix, dass sie nicht einmal angezeigt werden. Ruft man env mit einem Programmnamen auf, so durchsucht er das dem User zugängliche Envrionment nach genau diesem angegebenen Befehl und versucht ihn dann aufzurufen.
Damit wir jetzt Prozesse starten können, die in einer anderen Prozessumgebung laufen, gibt es die beiden Tools su und sudo. Der Unterschied zwischen beiden liegt schon im Namen su heßt SwitchUserkontext und sudo SwitchUserkontextAndDO. Die Arbeitsweise ist sehr ähnlich, aber es gibt einen gravierenden Unterschied. Um den verstehen zu können, müssen wir noch einen Überblick haben, was eine Shell beim Aufruf eines Programmes alles erledigt, und welche Dinge dafür relevant sind. Weshalb wir uns kurz angucken,
wie eine Shell generell arbeitet.
Die bash kennt viele Modi, in denen sie arbeiten kann, und sie berücksichtigt beim Aufruf viele sogenannte "Dotfiles". Die dienen per traditioneller Konvention der Konfiguration. Laut dem Sourcecode der bash Die kennt folgende "Konfigurationsdateien": /etc/profile, /etc/bash.bashrc, ~/.bash_profile, ~/.bash_login und zu guter Letzt gibt es noch ein Script, das ausgeführt wird, wenn die bash beendet wird: ~/.bash_logout.
Letztlich sind alle diese Dateien gültige Shellscripte, die einfach "gesourced" werden. Steht in irgendeinem Shellscript eine Zeile, wie source /Pfad/zu/irgendeinem/Shellscript (oder die dazu synonyme Kurzform . /Pfad/zu/irgendeinem/Shellscript ), so wird diese Zeile durch den gesamten Inhalt dieses Scripts ersetzt, also somit anstelle dieser Sourcezeile ausgeführt.
Es gibt so viele Dateien, weil ja völlig verschiedene Shellszenarien bedient sein wollen. Die Umgebung einer Shell hängt nicht nur von den Rechten des jeweiligen Users ab, sondern natürlich auch noch von anderen Faktoren. Ein User, der direkt vor dem Keyboard eines Linuxrechners sitzt, hat eine andere Shellumgebung, wie ein User, der sich via ssh über das Netzwerk einloggt. Es gibt noch ein paar Umstände, die zu berücksichtigen wären, wie z.B. ein System, auf dem teilweise User in einer chroot Umgebung arbeiten, andere nicht.
Und weil das immer noch nicht kompliziert genug ist, sourced die Bash noch ganze Verzeichnisse, wie z.B. /etc/bash_completion.d/*, in dem jede Menge Shellscripts liegen, die in der Shell dann Completion- Funktionen bereitstellen.
Und natürlich kann jeder User noch selbst kräftig rumsourcen.
Es ist also nicht ganz klar, ich welcher Reihenfolge welche Dateien bei der Konfiguration einer gerade aufgerufenen Shell mitspielen.
Außerdem könnte es auch noch sein, dass ein User ein Script gänzlich ohne ein Terminal laufen lässt, sich also weder über eine Loginshell, sei die lokal oder remote gerufen. Ein "detached"er Hintergrundprozess. screen wäre da so ein typisches Beisiel dafür.