cd
ist 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 bash
Handbuch :
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 cd
vorstellen, 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 cd
Programm 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 cd
Programms oder etwas anderes. Das ist eine ganze Dose Würmer.
Oder Sie könnten ein cd
Programm haben, das den chdir
Systemaufruf 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
echo
und test
sind von POSIX beauftragte Dienstprogramme ( /bin/echo
und /bin/test
). Dennoch hat fast jede populäre Muschel ein eingebautes echo
und test
. Ebenso kill
ist 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 PATH
wä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 dash
Quelle 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
evalcommand
wird 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.cmd
ist struct
( struct builtincmd
), eine von deren Mitglieder ein Funktionszeiger, mit einer Signatur typisch main
: (int, char **)
. Die evalbltin
Funktion ruft (abhängig davon, ob der eingebaute eval
Befehl der Befehl ist oder nicht) entweder evalcmd
diesen Funktionszeiger auf. Die eigentlichen Funktionen sind in verschiedenen Quelldateien definiert. echo
Zum 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 cd
ausfü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 .
type
Befehl