cdist eine POSIX- mandated Shell eingebaut:
Wenn ein einfacher Befehl einen Befehlsnamen und eine optionale Liste von Argumenten ergibt, müssen die folgenden Aktionen ausgeführt werden:
- Wenn der Befehlsname keine Schrägstriche enthält, wird der erste erfolgreiche Schritt in der folgenden Reihenfolge ausgeführt:
...
- Wenn der Befehlsname mit dem Namen eines in der folgenden Tabelle aufgelisteten Dienstprogramms übereinstimmt, wird dieses Dienstprogramm aufgerufen.
...
cd
...
- Andernfalls soll der Befehl mit PATH gesucht werden ...
Dies bedeutet zwar nicht ausdrücklich, dass es sich um ein eingebautes Produkt handeln muss, die Spezifikation geht jedoch in die Beschreibung voncd :
Da sich cd auf die aktuelle Shell-Ausführungsumgebung auswirkt, wird es immer als reguläre integrierte Shell bereitgestellt.
Aus dem bashHandbuch :
Die folgenden in die Shell eingebauten Befehle werden von der Bourne-Shell geerbt. Diese Befehle werden gemäß dem POSIX-Standard implementiert.
...
cd
cd [-L|[-P [-e]]] [directory]
Ich nehme an, Sie könnten sich eine Architektur cdvorstellen, bei der es sich nicht unbedingt um eine eingebaute Architektur handeln muss. Sie müssen jedoch sehen, was ein eingebautes impliziert. Wenn Sie speziellen Code in die Shell schreiben, um etwas für einen bestimmten Befehl zu tun, haben Sie fast ein eingebautes Programm. Je mehr Sie tun, desto besser ist es, einfach ein eingebautes zu haben.
Beispielsweise könnte die Shell IPC für die Kommunikation mit Unterprozessen haben, und es würde ein cdProgramm geben, das prüft, ob das Verzeichnis vorhanden ist und ob Sie die Zugriffsberechtigung dafür haben, und kommuniziert dann mit der Shell, um ihr anzuweisen, das Verzeichnis zu ändern Verzeichnis. Sie müssen dann jedoch überprüfen, ob der mit Ihnen kommunizierende Prozess ein untergeordnetes Element ist (oder nur spezielle Kommunikationsmittel wie einen speziellen Dateideskriptor, einen gemeinsam genutzten Speicher usw. bereitstellen) und ob der Prozess tatsächlich ausgeführt wird Ausführen des vertrauenswürdigen cdProgramms oder etwas anderes. Das ist eine ganze Dose Würmer.
Oder Sie könnten ein cdProgramm haben, das den chdirSystemaufruf ausführt und eine neue Shell mit allen aktuellen Umgebungsvariablen startet, die auf die neue Shell angewendet werden, und dann die übergeordnete Shell (irgendwie) beendet, wenn dies erledigt ist. 1
Schlimmer noch, Sie könnten sogar ein System haben, in dem ein Prozess die Umgebung anderer Prozesse verändern kann (technisch gesehen können Sie dies mit Debuggern tun). Ein solches System wäre jedoch sehr, sehr anfällig.
Sie werden feststellen, dass Sie immer mehr Code hinzufügen, um solche Methoden abzusichern, und es ist erheblich einfacher, ihn einfach zu einem eingebauten Code zu machen.
Dass etwas eine ausführbare Datei ist, hindert es nicht daran, eingebaut zu sein. Ein typisches Beispiel:
echo und test
echound testsind von POSIX beauftragte Dienstprogramme ( /bin/echound /bin/test). Dennoch hat fast jede populäre Muschel ein eingebautes echound test. Ebenso killist auch eingebaut, was als Programm zur Verfügung steht. Andere sind:
sleep (nicht so häufig)
time
false
true
printf
Es gibt jedoch einige Fälle, in denen ein Befehl nur ein integrierter Befehl sein kann. Eine davon ist cd. Wenn der vollständige Pfad nicht angegeben wird und der Befehlsname mit dem eines integrierten Befehls übereinstimmt, wird in der Regel eine für diesen Befehl geeignete Funktion aufgerufen. In Abhängigkeit von der Schale, das Verhalten des builtin und dass die ausführbaren Datei unterscheiden kann (dies ist vor allem ein Problem fürecho die , die hat wild unterschiedliche Verhaltensweisen . Wenn Sie bestimmt das Verhalten sein will, ist es vorzuziehen , die ausführbare Datei mit der rufen vollständiger Pfad und setze Variablen wie POSIXLY_CORRECT(auch dann gibt es keine wirkliche Garantie).
Technisch gesehen hindert Sie nichts daran, ein Betriebssystem bereitzustellen, das auch eine Shell ist und in dem jeder Befehl integriert ist. Nahe an diesem äußersten Ende befindet sich die monolithische BusyBox . BusyBox ist eine einzelne Binärdatei, die sich (abhängig vom Namen, mit dem sie aufgerufen wird) wie eines von über 240 Programmen verhalten kann , einschließlich einer Almquist-Shell ( ash). Wenn Sie die Einstellung PATHwährend der Ausführung der BusyBox aufheben ash, können Sie weiterhin auf die in BusyBox verfügbaren Programme zugreifen, ohne a anzugeben PATH. Sie sind beinahe Shell-Builtins, mit der Ausnahme, dass die Shell selbst eine Art Builtin für BusyBox ist.
Wenn Sie sich die dashQuelle ansehen, sieht der Ausführungsthread ungefähr so aus (natürlich mit zusätzlichen Funktionen, wenn Pipes und andere Dinge verwendet werden):
main→ cmdloop→ evaltree→evalcommand
evalcommandwird dann verwendet findcommand, um zu bestimmen, was der Befehl ist. Wenn es ein eingebautes ist, dann :
case CMDBUILTIN:
if (spclbltin > 0 || argc == 0) {
poplocalvars(1);
if (execcmd && argc > 1)
listsetvar(varlist.list, VEXPORT);
}
if (evalbltin(cmdentry.u.cmd, argc, argv, flags)) {
if (exception == EXERROR && spclbltin <= 0) {
FORCEINTON;
break;
cmdentry.u.cmdist struct( struct builtincmd), eine von deren Mitglieder ein Funktionszeiger, mit einer Signatur typisch main: (int, char **). Die evalbltinFunktion ruft (abhängig davon, ob der eingebaute evalBefehl der Befehl ist oder nicht) entweder evalcmddiesen Funktionszeiger auf. Die eigentlichen Funktionen sind in verschiedenen Quelldateien definiert. echoZum Beispiel ist :
int
echocmd(int argc, char **argv)
{
int nonl;
nonl = *++argv ? equal(*argv, "-n") : 0;
argv += nonl;
do {
int c;
if (likely(*argv))
nonl += print_escape_str("%s", NULL, NULL, *argv++);
if (nonl > 0)
break;
c = *argv ? ' ' : '\n';
out1c(c);
} while (*argv);
return 0;
}
Alle Links zum Quellcode in diesem Abschnitt basieren auf Zeilennummern. Sie können sich daher ohne vorherige Ankündigung ändern.
1 POSIX-Systeme haben eine cdausführbare Datei .
Randnotiz:
Unter Unix & Linux gibt es eine Menge exzellenter Beiträge, die sich mit dem Shell-Verhalten befassen. Bestimmtes:
Wenn Sie in den bisher aufgeführten Fragen kein Muster bemerkt haben, sind fast alle von Stéphane Chazelas betroffen .
typeBefehl