Plausibilitätsprüfung:Soweit ich weiß, ist die Shell die Schnittstelle, über die der Benutzer mit dem Betriebssystem interagieren kann, dh:andere Prozesse ausführen kann.
Ja, aber eine "Shell" ist speziell ein Benutzer Schnittstelle, keine Programmierschnittstelle. Andere Programme müssen nicht damit interagieren – sie können direkt dieselben Systemaufrufe verwenden, um neue Prozesse zu erstellen.
Die Kommandozeilen-Shell befindet sich also auf der gleichen Ebene wie andere Programme, z. Dienstmanager oder grafische Benutzerschnittstellen (grafische Shells).
Obwohl die Shell (z. B. Bash) nur ein weiterer Prozess ist.
Ja. Auf Unix-ähnlichen Systemen ist es ein völlig normaler, unprivilegierter Prozess.
Gibt es eine Möglichkeit, einen Prozess auszuführen, der kein Kind eines Shell-Prozesses ist?
Aus Benutzersicht:Ja, es gibt mehrere Möglichkeiten.
-
Die meisten Muscheln haben einen
exec
Schlüsselwort, das bewirkt, dass das neue Programm ersetzt wird die Shell (die dieselbe PID und Elternschaft beibehält), was wahrscheinlich nicht das war, was Sie meinten, aber technisch gesehen das, wonach Sie gefragt haben. -
Grafische Desktop-Sitzungen werden oft gestartet, ohne Bash oder eine andere Shell aufzurufen, und dies gilt automatisch für Apps, die über die grafischen Menüs gestartet werden. Das übergeordnete Element der App ist der Prozess, der für die Anzeige des Menüs verantwortlich war (z. B. der Fenstermanager oder das Bedienfeld).
-
Das derzeit beliebte systemd Das init-System verwendet beim Starten von Diensten überhaupt keine Shell, sodass Sie eine .service definieren und starten können – der übergeordnete Dienst des Dienstes ist init selbst. Es hat auch eine Funktion, mit der temporäre Dienste mit
systemd-run
on-the-fly erstellt werden können , mit den gleichen Ergebnissen.
Aus der Sicht eines Programmierers verwenden Sie einfach den fork()
und execve()
Systemaufrufe zum Starten eines neuen Prozesses. (Es gibt betriebssystemspezifische Details, z. B. kann fork() tatsächlich ein Wrapper für einen anderen Aufruf sein, aber es funktioniert immer noch auf die gleiche Weise.)
Selbst wenn das Programm eine Shell aufrufen wollte, würde es dies tun, indem es einen neuen untergeordneten Prozess erstellt und /bin/sh mit demselben fork+exec ausführt. Es gibt keinen speziellen Systemaufruf, um eine Shell auszuführen. (Der Programmierer könnte z. B. system() beim Schreiben in C oder os.system() in Python verwenden, aber das sind immer noch nur bequeme Wrapper um fork/exec.)
Umgebungsvariablen:In Bash gibt es mehrere Skripte, die ausgeführt werden, wenn Sie eine Shell erzeugen, z. .bashrc, .bash_profile usw. (hängt von der Art der Shell ab – interaktiv vs. nicht interaktiv, Login vs. Nicht-Login). Diese Skripte definieren die Umgebungsvariablen. Wenn es eine Möglichkeit gibt, einen Prozess unabhängig von einer Shell auszuführen, woher kommen Umgebungsvariablen?
Nun, manchmal tun sie das nicht. (Es ist ein echtes praktisches Problem, wenn man versucht, grafische Apps dazu zu bringen, Umgebungsanpassungen aufzunehmen, je nachdem, wie diese bestimmte grafische Umgebung startet.)
Insgesamt sind Umgebungsvariablen jedoch nicht einzigartig für CLI-Shells. Jeder Prozess, egal wie er gestartet wurde (einschließlich des Init-Prozesses), erhält ein Array von Strings, das seine Befehlszeile enthält – und ein Array von Strings, das seine Umgebungsvariablen enthält. Beim Starten eines untergeordneten Prozesses kann dieser entweder eine andere Umgebung angeben oder zulassen, dass eine Kopie seiner eigenen Umgebung geerbt wird.
Wenn Sie sich also anmelden, erhält Ihre Shell bereits einige anfängliche Umgebungsvariablen von ihrem übergeordneten Element. Diese Startskripte (bashrc usw.) sind nur ein bequemer Ort für einen Benutzer, um die Umgebungsvariablen anzupassen, die die untergeordneten Prozesse der Shell dann erben werden.
Viele Teile dieser Antwort gelten auch uneingeschränkt für Windows – obwohl die grafische Oberfläche etwas komplexer ist, sind die CLI-Shells (cmd.exe und PowerShell) immer noch gewöhnliche Programme, die im normalen Betrieb überhaupt nicht verwendet werden. Der einzige große Unterschied besteht darin, dass Windows einen einzigen „CreateProcess“-Aufruf anstelle der separaten „fork + exec“-Aufrufe im Unix-Stil hat.
-
Das ist richtig. Letztendlich führt die Shell den
exec
aus Systemaufruf, der in allen POSIX-kompatiblen Betriebssystemen und allgemeiner in allen Unix-ähnlichen Betriebssystemen, einschließlich Linux, verfügbar ist. Andere Betriebssysteme haben ähnliche Konzepte. Unter Linux derexec
Der Systemaufruf ruft letztendlichexecve
auf Funktion, die vom Kernel bereitgestellt wird und die eigentliche Aufgabe übernimmt, die ausführbare Datei zu laden und auszuführen. -
Ja. Jeder Prozess kann
exec
aufrufen , und muss keine "Hülle" sein. Wenn Sie beispielsweise ein Programm durch Klicken in einen Dateisystembrowser starten, ist die Desktop-Software diejenige, dieexec
ausführt Rufen Sie an, es gibt keine Schale. Beachten Sie, dass der Prozess das Kind der Desktop-Software wird, die ihn gestartet hat. Alle Prozesse sind die Kinder eines anderen Prozesses, mit Ausnahme des allerersten, derinit
heißt und hat die PID 1. Sie ist für die Einrichtung des Betriebssystems beim Start und den Start aller anderen Prozesse wie Hintergrunddienste und Desktop-Anmeldung verantwortlich. Unter Linux heutzutagesystemd
wird oft alsinit
verwendet Prozess, aber es gibt andere Alternativen. -
Es gibt mehrere Varianten von
exec
(execl
,execle
, ...), die neben dem Namen des auszuführenden Programms verschiedene Argumente haben. Letztendlich dieexecve
Der Systemaufruf nimmt einen Programmnamen, eine Liste von Zeichenfolgen, die die Befehlszeilenargumente sind, und eine Liste von Zeichenfolgen, die die Umgebungsvariablen sind. Wenn beispielsweise Software von einem Dateisystembrowser gestartet wird, können die Umgebungsvariablen von denen des Dateisystembrowsers selbst kopiert und möglicherweise durch den Dateisystembrowser modifiziert werden. Dies liegt ganz bei den Programmierern des Dateisystembrowsers.
Etwas weiterführende Lektüre:
- https://en.wikipedia.org/wiki/Exec_(system_call)
- https://en.wikipedia.org/wiki/Fork%E2%80%93exec
- https://man7.org/linux/man-pages/man2/execve.2.html