Grundlegendes zu integrierten Shell-Befehlen


12

Im Bash-Handbuch steht das geschrieben

Builtin commands are contained >>> within <<< the shell itself

Auch diese Antwort besagt, dass

A built-in command is simply a command that the shell carries out itself,
instead of interpreting it as a request to load and run some
>>> other program <<<

Wenn ich laufe compgen -bauf bash 4.4, erhalte ich eine Liste aller Shell - builtin - Befehle. Ich sehe das zum Beispiel [und bin killals Shell Builtins aufgeführt. Aber ihre tatsächlichen Standorte sind:

/usr/bin/[
/bin/kill

Ich dachte, dass dies builtinbedeutet, dass der Befehl in die /bin/bashausführbare Datei kompiliert wird . Was mich also wirklich verwirrt: Bitte korrigieren Sie mich, aber wie kann ein separater Befehl ein sein builtin, wenn er tatsächlich nicht Teil der Shell ist?


1
Einige Befehle existierten ursprünglich als separate Dienstprogramme. Ihre Präsenz dient nun der Einhaltung des POSIX-Standards, der Portabilität sowie der Abwärtskompatibilität. Shells implementieren einige, wie sie für die Leistung eingebaut sind. Es mag einen anderen Grund geben, aber das ist ohne allzu viele Details.
Sergiy Kolodyazhnyy

1
Ein weiterer Grund, an den ich denken könnte, ist, dass einige integrierte Befehle speziell für die Shell benötigt werden, z. B. execzum Bearbeiten von Dateideskriptoren und eval zum Auswerten von Befehlen. Sie werden nicht als eigenständige Befehle benötigt
Sergiy Kolodyazhnyy

Antworten:


16

Die Befehle, die in die Shell integriert sind, sind aufgrund der damit verbundenen Leistungssteigerung häufig integriert. Das Aufrufen des externen Geräts printfist beispielsweise langsamer als das Verwenden des integrierten Geräts printf.

Da einige Dienstprogramme nicht brauchen in gebaut werden, es sei denn , sie sind speziell, wie cd, werden sie auch als vorgesehen externe Dienstprogramme. Auf diese Weise werden Skripte nicht beschädigt, wenn sie von einer Shell interpretiert werden, die kein integriertes Äquivalent bietet.

Einige integrierte Shell-Funktionen bieten auch Erweiterungen für den externen äquivalenten Befehl. Bash's printfzum Beispiel kann das

$ printf -v message 'Hello %s' "world"
$ echo "$message"
Hello world

(Drucken in eine Variable), was der Externe /usr/bin/printfeinfach nicht kann, da er in der aktuellen Shell-Sitzung keinen Zugriff auf die Shell-Variablen hat (und diese nicht ändern kann).

Eingebaute Dienstprogramme unterliegen auch nicht der Einschränkung, dass ihre erweiterte Befehlszeile kürzer als eine bestimmte Länge sein muss. Tun

printf '%s\n' *

ist daher sicher, wenn printfein Shell-Befehl eingebaut ist. Die Einschränkung der Länge der Befehlszeile ergibt sich aus der execve()C-Bibliotheksfunktion, mit der ein externer Befehl ausgeführt wird. Wenn die Befehlszeile und die aktuelle Umgebung größer als ARG_MAXBytes sind (siehe getconf ARG_MAXin der Shell), schlägt der Aufruf von execve()fehl. Wenn das Dienstprogramm in die Shell integriert ist, execve()muss es nicht aufgerufen werden.

Eingebaute Dienstprogramme haben Vorrang vor Dienstprogrammen in $PATH. bashVerwenden Sie zum Deaktivieren eines integrierten Befehls z

enable -n printf

Es ist eine kurze Liste von Utilities , dass Bedarf in eine Schale (aus dem POSIX - Standard ist genommen gebaut werden Liste der speziellen Einbauten )

break
colon (:)
continue
dot (.)
eval
exec
exit
export
readonly
return
set
shift
times
trap
unset

Diese müssen integriert werden, da sie die Umgebung und den Programmablauf der aktuellen Shell-Sitzung direkt manipulieren. Ein externes Dienstprogramm wäre dazu nicht in der Lage.

Interessanterweise cdist nicht Teil dieser Liste, aber POSIX sagt dazu Folgendes :

Da sich dies cdauf die aktuelle Shell-Ausführungsumgebung auswirkt, wird sie immer als reguläre integrierte Shell bereitgestellt. Wenn es in einer Subshell oder einer separaten Ausführungsumgebung für Dienstprogramme aufgerufen wird, z. B. in einer der folgenden Umgebungen:

(cd /tmp)
nohup cd
find . -exec cd {} \;

Dies hat keine Auswirkungen auf das Arbeitsverzeichnis der Anruferumgebung.

Ich gehe daher davon aus, dass die "speziellen" Einbauten keine externen Gegenstücke haben können, obwohl dies cdtheoretisch möglich wäre (aber es würde nicht sehr viel bewirken).


IIRC, chdir/ cdwaren externe Binärdateien in sehr frühen Unices / Pre-Unix, bevor sie forkeingeführt wurden.
Xophmeister

@Xophmeister Solaris 11.4 (Beta) hat noch /usr/bin/cd, aber es wird nicht das aktuelle Arbeitsverzeichnis ändern. Das Handbuch besagt: /usr/bin/cdHat keine Auswirkung auf den Aufrufvorgang, kann jedoch verwendet werden, um zu bestimmen, ob ein bestimmtes Verzeichnis als aktuelles Verzeichnis festgelegt werden kann oder nicht.
Kusalananda

2
Ein weiterer, eher spezifischer Grund für Builtins: Builtin killist auch gut, weil es keinen weiteren Prozess verzweigen muss. Gut, wenn Sie das Limit für die Anzahl der Prozesse erreicht haben.
Derobert

7

Sie sind (sehr verständlich) verwirrt darüber, dass einige integrierte Funktionen sowohl als integrierte als auch als externe Befehle vorhanden sind. Wenn Sie also Recht haben, dass es beispielsweise einen /bin/[Befehl gibt, bedeutet dies nicht, dass sich der "tatsächliche Standort" darin befindet /bin.

Eine einfache Möglichkeit, dies zu testen, besteht darin, typemit dem -aSchalter zu arbeiten, der alle verfügbaren Instanzen eines Befehls anzeigt. Auf meinem Arch-System zeigt das:

$ type -a [
[ is a shell builtin
[ is /sbin/[
[ is /usr/sbin/[
[ is /usr/bin/[

Beachten Sie, dass /sbin, /usr/sbinund /binsind alle Symlinks zeigen auf /usr/bin, so dass es nur eine externe ist [:

$ readlink -f /usr/sbin /sbin /bin/
/usr/bin
/usr/bin
/usr/bin

Wie Sie sehen können, [handelt es sich sowohl um einen eingebauten als auch um einen externen Befehl, und das Gleiche gilt für verschiedene andere eingebaute Shell-Befehle. Dies ändert jedoch nichts an der Tatsache, dass es sich auch um Shell-Builds handelt, die in die Shell selbst kompiliert wurden.


warum distro. separaten externen Befehl für einen bereits vorhandenen internen Befehl bereitstellen? warum duplizieren sie?
LoveWithMaths

1
@linuxuser Einige dieser Dienstprogramme werden von POSIX benötigt, und Sie können nicht wissen, ob die Shell, die ein Benutzer gerade verwendet, auch eine integrierte Funktion bietet. Betrachten Sie sie nicht als internen Befehl des Betriebssystems, sie sind nur interne Befehle der Shell, und die Shell kann sich ändern.
Terdon

Ich habe jetzt 1 Zweifel, ob interne Befehle von der Shell bereitgestellt werden; Wer liefert dann externe Befehle? Wie ich viele Befehle beobachtet habe, die sowohl als interner als auch als externer Befehl verfügbar sind, aber ich habe sie nicht explizit installiert. Wer gibt also externe Befehle? Distribution bietet sie richtig?
LoveWithMaths

@linuxuser hängt vom Befehl und vom Betriebssystem ab. Zum Beispiel wird auf meinem Arch Linux /bin/printfvom coreutilsPaket und /bin/killvon installiert util-linux.
Terdon

Es tut mir leid, aber ich bin immer noch unklar, welche der oben genannten wird von der Distribution bereitgestellt? und was ist mit dem anderen, der nicht von der Distribution bereitgestellt wird, wer es dann bereitstellt?
LoveWithMaths
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.