Was ist der Unterschied zwischen einem eingebauten und einem nicht eingebauten Befehl?

72

Gibt es einen wesentlichen Unterschied zwischen einem eingebauten Befehl und einem anderen Befehl, der nominell dasselbe tun kann?

z.B. Erhalten Builtins eine "besondere" Behandlung? ... gibt es weniger Overhead, der sie laufen lässt? .. oder sind sie einfach "eingebaut"; wie das Armaturenbrett Ihres Autos?

... und gibt es eine definitive (aktuelle) Liste dieser Builtins?

Peter.O
quelle

Antworten:

90

Aus Ihren Kommentaren geht hervor, dass Sie verwirrt darüber sind, was genau eine Shell ist. Der Kernel ist für die Verwaltung des Systems verantwortlich. Es ist der Teil, der Programme lädt und ausführt, auf Dateien zugreift, Speicher zuweist usw. Aber der Kernel hat keine Benutzeroberfläche; Sie können nur mit einem anderen Programm als Vermittler kommunizieren.

Eine Shell ist ein Programm, das eine Eingabeaufforderung ausgibt, eine Eingabezeile liest und sie dann als einen oder mehrere Befehle zum Bearbeiten von Dateien oder zum Ausführen anderer Programme interpretiert. Vor der Erfindung der grafischen Benutzeroberfläche war die Shell die primäre Benutzeroberfläche eines Betriebssystems. Unter MS-DOS wurde die Shell aufgerufen, command.comund nur wenige Benutzer haben jemals versucht, eine andere zu verwenden. Unter Unix gab es jedoch schon lange mehrere Shells , aus denen Benutzer auswählen konnten.

Sie können in 3 Typen unterteilt werden. Die Bourne-kompatiblen Shells verwenden die von der ursprünglichen Bourne-Shell abgeleitete Syntax . C-Shells verwenden die Syntax der ursprünglichen C-Shell . Dann gibt es nicht-traditionelle Shells, die ihre eigene Syntax erfinden oder sich eine aus einer Programmiersprache leihen und im Allgemeinen viel weniger beliebt sind als die ersten beiden Typen.

Ein eingebauter Befehl ist einfach ein Befehl, den die Shell selbst ausführt, anstatt ihn als Aufforderung zum Laden und Ausführen eines anderen Programms zu interpretieren. Dies hat zwei Haupteffekte. Erstens ist es normalerweise schneller, da das Laden und Ausführen eines Programms einige Zeit in Anspruch nimmt. Je länger die Ausführung des Befehls dauert, desto weniger signifikant ist die Ladezeit im Vergleich zur Gesamtlaufzeit (da die Ladezeit ziemlich konstant ist).

Zweitens kann ein eingebauter Befehl den internen Zustand der Shell beeinflussen. Deshalb cd müssen Befehle wie eingebaut sein, da ein externes Programm das aktuelle Verzeichnis der Shell nicht ändern kann. Andere Befehle, wie z. B. echo, sind möglicherweise aus Effizienzgründen eingebaut, aber es gibt keinen eigentlichen Grund, warum es sich nicht um externe Befehle handeln kann.

Welche Befehle integriert sind, hängt von der verwendeten Shell ab. In der Dokumentation finden Sie eine Liste (die bashintegrierten Befehle finden Sie in Kapitel 4 des Handbuchs ). Der typeBefehl kann Ihnen mitteilen, ob ein Befehl eingebaut ist (wenn Ihre Shell POSIX-kompatibel ist), da POSIX typedies als eingebaut voraussetzt. Wenn whichin Ihrer Shell keine integrierte Komponente vorhanden ist, werden die integrierten Komponenten Ihrer Shell wahrscheinlich nicht erkannt, sondern es wird nur nach externen Programmen gesucht.

cjm
quelle
Anwendungen kommunizieren mit dem Kernel, indem sie Interrupts ausgeben.
Nathan Osman
11
@ George: Anwendungen kommunizieren mit dem Kernel, indem sie Syscalls ausgeben, die je nach Betriebssystem und Architektur möglicherweise Interrupts verwenden oder nicht. Benutzer geben in der Regel keine Interrupts aus.
Gilles
2
@cjm: Es klingt so einfach, wenn du es so erklärst:) ... du hast mit Sicherheit geholfen, den Nebel zu beseitigen ... jetzt nur noch ein leichter Nebel. .. angenehm neblig;) ... danke
Peter.O
@ Gilles: Wirklich? Ich dachte, alle Programme im Benutzermodus kommunizierten über Interrupts mit dem Kernel (auf bestimmten Architekturen natürlich).
Nathan Osman
2
@cjm Sehr gründliche und lehrreiche Antwort. Ich habe viel gelernt, es zu lesen. :)
Ankush981
37

Es gibt drei Ebenen von integrierten Dienstprogrammen:

  • Einige Dienstprogramme sind wirklich Teil der Shell als Programmiersprache, obwohl sie keine reservierten Wörter sind . Sie sind Steuerfluß Utilities ( ., :, break, continue, return, trap, exit, exec, eval), parameter zugehörigen Werkzeuge ( set, unset, shift, export, readonly, local¹, typeset¹), Alias - Dienstprogramme ( alias², unalias²) und times³. Diese speziellen Einbauten erhalten eine Sonderbehandlung:

    • Wenn Sie die falschen Argumente an ein spezielles eingebautes Programm übergeben, wird die Shell möglicherweise abgebrochen, anstatt nach dem Anzeigen einer Fehlermeldung zum nächsten Befehl zu springen.
    • Die Pre-Assignment-Syntax foo=bar utilityhat eine andere Bedeutung: Es handelt sich um eine gewöhnliche Parameterzuweisung (dh äquivalent zu foo=bar; utility), anstatt sie nur für die Dauer des Dienstprogramms der Umgebung zuzuweisen.
  • Einige Dienstprogramme müssen in der Shell implementiert werden, da sie sich auf die internen Einstellungen der Shell auswirken. Das beinhaltet:

    • Dienstprogramme , die auf die Shell des aktuellen Verzeichnisses handeln wie cd, dirs, pushd, popd;
    • Auftragssteuerung Dienstprogramme wie bg, disown, fg, jobs, wait;
    • Dienstprogramme , die andere Schale Attribute wie lesen oder manipulieren builtin, command, hash, read, type, ulimit, umask;
    • Dienstprogramme interaktive Funktionen im Zusammenhang, wenn sie vorhanden ist , wie sind fc, history, bind.
  • Einige Dienstprogramme sind in der Regel als Einbauten rein umgesetzt Leistung : echo, printf, test, true, false.

Erweiterte Shells wie bash , ksh und zsh verfügen in der Regel über mehr integrierte Funktionen, um nicht standardmäßige Funktionen zu implementieren (normalerweise für die Interaktion). Das Handbuch jeder Shell gibt Auskunft darüber, welche Befehle integriert sind, obwohl einige Shells ( zumindest zsh ) dynamisch ladbare Module unterstützen, die mehr integrierte Funktionen bieten.

¹ POSIX unbekannt, jedoch speziell in ksh und mehreren anderen Shells.
² Gewöhnlich in POSIX, aber speziell in ksh und einigen anderen Shells.
³ In ksh, timesist ein Wrapper um das timeStichwort: es ist ein Alias für { { time;} 2>&1;}. Beachten Sie, dass POSIX timeein externes Dienstprogramm mit normalem Parsing oder ein Schlüsselwort sein kann, das für eine gesamte Pipeline gilt (in ksh, in zsh bash).

Gilles
quelle
3
Diese Unterscheidungen sind die wirklich wichtigen.
dmckee
Kurze Frage, was bedeutet dann "normale Parametrierung" while IFS= read -r line?
Sergiy Kolodyazhnyy
@SergiyKolodyazhnyy readist keine spezielle Funktion, daher wird IFS=readdie Variable nur für die Dauer des Befehls festgelegt.
Gilles
10

Ein Builtin ist ein Befehl, der von der Shell und nicht von einem externen Programm bereitgestellt wird. Hier sind die Listen für bashdie eingebauten Funktionen (sie sind auch in der Bash-Manpage aufgeführt) und zshdie eingebauten Funktionen . kshLiefert eine Liste durch Ausführen builtin.

Wenn Sie wissen möchten, ob ein bestimmter Befehl ein integrierter Befehl ist, können Sie ihn ausführen type command. Versuchen Sie type forund dies type lszu sehen.

Shawn J. Goff
quelle
typescheint den Trick zu tun; danke dafür ... aber ich frage mich immer noch, was "von der Shell bereitgestellt" bedeutet ... Vielleicht muss ich besser verstehen, wie sich die Shell auf den Kernel bezieht ... aber nicht um 2 Uhr morgens. Ich werde kommen zurück zu diesem morgen
Peter.O
1

Jede Distribution und Shell hat eine andere Sammlung von Befehlen als die eingebauten Shell-Funktionen. Im Allgemeinen besteht die Idee darin, dass Shells die gebräuchlichsten und einfachsten Funktionen einbauen, um Zeit, Geschwindigkeit und Integrationswillen mit dem Rest ihres Funktionsumfangs zu sparen. Der Overhead ist viel geringer, da kein weiterer Systemprozess gestartet werden muss. Es ist jedoch möglich, zu mischen und anzupassen. Sie können eine Shell ausführen, die ein Build für etwas hat, aber diesen Befehl auch auf Ihrem System haben. Normalerweise hat der eingebaute Code Priorität, aber Sie können dies steuern.

Sie können leicht herausfinden, ob ein bestimmter Befehl ein integrierter Befehl ist oder nicht, indem Sie ihn ausführen type mycommand. Die meisten Shell-Manpages enthalten auch eine Liste ihrer eingebauten Funktionen.

Bearbeiten: Verwenden typeSie diese Option, um herauszufinden, ob es sich bei einem Befehl um einen eingebauten Befehl handelt, und um whichzu erfahren, woher er ausgeführt wird.

Caleb
quelle
@Caleb: Danke für deinen Kommentar, aber ich frage mich, was genau ein "Systemprozess" ist. Ich sehe immer wieder Verweise darauf, aber ich verstehe nicht, wo der Unterschied liegt ... (Übrigens kann ich nicht sehen, wie 'welches' ein absoluter Indikator ist) .. zB .. 'welcher Echotyp =>"/bin/echo" and echo =>"echo is a shell builtin", but 'which dd=> "/ bin / dd" und type dd=> "dd ist / bin / dd" ... also bin ich auf halbem Weg da ....
Peter.O
"System Processes" bedeutet nur, dass es als unabhängige, vom Kernel verwaltete Anwendung gestartet wird. Die Alternative bei Builtins besteht darin, eine Unterfunktion im bereits laufenden Code Ihrer Shell auszuführen. In dem von Ihnen angegebenen Beispiel typeist dies der bessere Indikator für die Ausführung. Sie stellen jedoch fest, dass echoes sich sowohl um eine integrierte Anwendung als auch um eine Anwendung mit diesem Namen handelt. Wenn Ihre Shell kein eingebautes System hätte, würde eines ausgeführt werden.
Caleb
2
whichist nicht unbedingt ein integrierter Befehl, und wenn dies nicht der Fall ist, werden die integrierten Funktionen der Shell nicht berücksichtigt. Für POSIX muss es sich typeum einen integrierten Befehl handeln, damit es immer über integrierte Befehle informiert ist.
cjm
Viele Systeme werden mit einem Alias whichzu typeoder einer Reihe von Optionen , zum Beispiel alias which='type -path'- könnte dies die Quelle der Verwirrung sein.
Random832
1
Ich kann das nicht unterstützen, bis whiches durch ersetzt wird type. Ich habe das immer wieder benutzt, ohne es zu wissen typeund war sehr erstaunt zu lernen, das whichist nur richtig, wenn ich mich zwischen Programmen entscheide.
Benutzer unbekannt