Ich habe es versucht which cd
und es hat keinen Pfad angegeben, sondern den Exit-Code 1 zurückgegeben (überprüft mit echo $?
). Das Coreutil cd
selbst funktioniert, also sollte die ausführbare Datei dort sein, oder? Ich habe auch eine find
for ausgeführt cd
, aber es wurde keine ausführbare Datei angezeigt. Wie wird es dann umgesetzt?
Aktualisieren:
Ich weiß nicht, ob ich das in einem anderen Beitrag fragen soll, aber da ich denke, dass es hier gut ist, erweitere ich den Beitrag (?) ... Die Antwort war also eigentlich ganz einfach, es gibt keine ausführbare Datei dafür - weil es ist a builtin - Aber ich habe festgestellt, dass einige builtins (bash shell in Fedora) die ausführbaren Dateien haben! Also eingebaut -> keine ausführbare Datei stimmt wohl nicht? Vielleicht eine Antwort, die erklärt, was Builtins eigentlich sind (Builtin-Befehle?), Und die hier eigentlich die Angelegenheit ist, anstatt sich mehr darauf zu konzentrieren cd
... Einige gute Links, die zuvor gepostet wurden, weisen darauf hin, dass Builtins keine Programme sind ... also, was sind sie? Wie arbeiten Sie? Sind sie nur Funktionen oder Threads der Shell?
quelle
type
Befehlcd
Frage und Antwort erfahren Sie, warum eine eingebaute CD sein muss: Warum ist CD kein Programm? und dieses auf warumtype
ist besser alswhich
: Warum nicht "welches" verwenden? Was ist dann zu verwenden?Antworten:
Befehl
cd
kann keine ausführbare Datei seinIn einer Shell
cd
wird verwendet, um "in ein anderes Verzeichnis zu wechseln" oder formeller, um das aktuelle Arbeitsverzeichnis (CWD) zu ändern. Es ist unmöglich, das als externen Befehl zu implementieren:Das Verzeichnis gehört zu einem Prozess
Das aktuelle Arbeitsverzeichnis ist das Verzeichnis, in dem relative Pfade interpretiert werden, um einen vollständigen Pfad zu erhalten, mit dem auf Dateien zugegriffen werden kann. Relative Pfade werden an vielen Stellen verwendet, und die Interpretation in einem Prozess sollte keinen Einfluss auf einen anderen Prozess haben.
Aus diesem Grund hat jeder Prozess ein eigenes aktuelles Arbeitsverzeichnis.
cd
Es geht beispielsweise darum, das aktuelle Arbeitsverzeichnis des Shell-Prozesses zu ändernbash
.Wenn es sich um einen externen Befehl handeln würde, würde eine ausführbare Datei im Pfad, die diese ausführbare Datei ausführt, einen Prozess mit einem eigenen Arbeitsverzeichnis erstellen, ohne das der aktuellen Shell zu beeinflussen. Selbst wenn der externe Befehl das Verzeichnis ändern würde, wird diese Änderung nicht mehr ausgeführt, wenn der externe Prozess beendet wird.
Shell eingebaute Befehle
Es macht also keinen Sinn, einen externen Befehl für die Aufgabe von auszuführen
cd
. Der Befehlcd
muss eine Änderung auf den aktuell ausgeführten Shell-Prozess anwenden.Dazu ist es ein "eingebauter Befehl" der Shell.
Builtin-Befehle sind Befehle, die sich ähnlich wie externe Befehle verhalten, jedoch in der Shell implementiert sind (also
cd
nicht Teil der coreutils sind). Auf diese Weise kann der Befehl den Status der Shell selbst ändern, in diesem Fallchdir()
see (seeman 2 chdir
) aufrufen .Über
which
Die Antwort auf die Titelfrage ist nun einfach:
Der ausführbare Befehl
which
kann uns nicht sagen, dass cd ein eingebauter Befehl ist, da ein ausführbarer Befehl nichts über eingebaute Befehle weiß.Alternative
type -a
Als Alternative zu
which
können Sie verwendentype -a
; Es können ausführbare Befehle und integrierte Befehle angezeigt werden. Zusätzlich werden Aliase und Funktionen angezeigt - ebenfalls in der Shell implementiert:quelle
cd
eine Shell eingebaut ist.cd
ist eine POSIX- mandated Shell eingebaut:Dies bedeutet zwar nicht ausdrücklich, dass es sich um ein eingebautes Produkt handeln muss, die Spezifikation geht jedoch in die Beschreibung von
cd
:Aus dem
bash
Handbuch :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ürdigencd
Programms oder etwas anderes. Das ist eine ganze Dose Würmer.Oder Sie könnten ein
cd
Programm haben, das denchdir
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. 1Schlimmer 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
undtest
echo
undtest
sind von POSIX beauftragte Dienstprogramme (/bin/echo
und/bin/test
). Dennoch hat fast jede populäre Muschel ein eingebautesecho
undtest
. Ebensokill
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 wiePOSIXLY_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 EinstellungPATH
während der Ausführung der BusyBox aufhebenash
, können Sie weiterhin auf die in BusyBox verfügbaren Programme zugreifen, ohne a anzugebenPATH
. Sie sind beinahe Shell-Builtins, mit der Ausnahme, dass die Shell selbst eine Art Builtin für BusyBox ist.Fallstudie: Die Debian-Almquist-Shell (
dash
)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 verwendetfindcommand
, um zu bestimmen, was der Befehl ist. Wenn es ein eingebautes ist, dann :cmdentry.u.cmd
iststruct
(struct builtincmd
), eine von deren Mitglieder ein Funktionszeiger, mit einer Signatur typischmain
:(int, char **)
. Dieevalbltin
Funktion ruft (abhängig davon, ob der eingebauteeval
Befehl der Befehl ist oder nicht) entwederevalcmd
diesen Funktionszeiger auf. Die eigentlichen Funktionen sind in verschiedenen Quelldateien definiert.echo
Zum Beispiel ist :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:
cd
externen Befehls?quelle
cd
mithelp cd
(dasselbe für alle Shell-Builtin-Befehle)help
ist eine Bash gebaut (für zsh, es istrun-help cd
)cd
dies als integrierte Shell erfolgen muss. Escd
ist jedoch die einzige unkomplizierte Implementierung , die darauf basiert, wie Prozesseigenschaften und deren Übertragung in UNIX als integrierte Shell funktionieren . Siehe die Antwort von Volker Siegel .Sie können keine ausführbare Datei für finden,
cd
da es keine gibt.cd
ist ein interner Befehl Ihrer Shell (zBbash
).quelle
von
man which
:Wie aus der Beschreibung von hervorgeht
which
, handelt es sich nur um eine ÜberprüfungPATH
. Wenn Sie also einige implementiert habenbash function
, wird Ihnen nichts angezeigt. Es ist besser,type
Befehl zusammen mit zu verwendenwhich
.Zum Beispiel in Ubuntu
ls
Befehl Alias aufls --color=auto
.Und wenn Sie Testfunktion implementieren
hello
:which
zeigt nichts. Abertype
:In Ihrem Fall:
Dies bedeutet, dass
cd
es sich um eine eingebaute Shell handelt , die sich im Inneren befindetbash
. Alle Bash-Befehleman bash
, die in Abschnitt SHELL BUILTIN COMMANDS beschrieben sindquelle
manwhich
.which
, verwendentype
.