cmd laufen Wenn ich Ihre Frage richtig verstanden, Sie fragen, wie kann etwas (insbesondere im Zusammenhang mit der Docker) ausgeführt werden, ohne eine Kommando-Shell aufrufen .
So wie die Dinge in dem Linux-Kernel ausgeführt werden, in der Regel the exec
family of system calls.
Sie verwenden, um die ausführbare Datei Sie ausführen es den Weg wollen passieren und die Argumente, die über einen execl Anruf beispielsweise an sie übergeben werden müssen.
Dies ist tatsächlich, was Ihre Shell (sh, bash, ksh, zsh) sowieso unter der Haube tut. Sie können dies selbst beobachten, wenn Sie so etwas wie strace -f bash -c "cat /tmp/foo"
In der Ausgabe dieses Befehls laufen Sie so etwas wie dies sehen werden:
execve("/bin/cat", ["cat", "/tmp/foo"], [/* 66 vars */]) = 0
Was wirklich los ist, dass bash up sieht cat
in $PATH
, es stellt dann fest, dass cat
tatsächlich eine ausführbare Binärdatei ist, die unter /bin/cat
verfügbar ist. Es ruft dann einfach über execve
auf. und die richtigen Argumente, wie Sie oben sehen können.
Sie können trivialerweise ein C-Programm schreiben, das dasselbe tut. Dies ist, was ein solches Programm würde so aussehen:
#include<unistd.h>
int main() {
execl("/bin/cat", "/bin/cat", "/tmp/foo", (char *)NULL);
return 0;
}
Jede Sprache mit diesen System von Schnittstellen Anrufe seine eigene Art und Weise zur Verfügung stellt. C tut, Python macht und Go, was auch das ist, was Docker zum größten Teil benutzt. Eine RUN
Anweisung im Andockfenster führt wahrscheinlich zu einem dieser exec
Aufrufe, wenn Sie docker build
drücken.Sie können eine strace -f docker build
und dann grep
für exec
Anrufe im Protokoll ausführen, um zu sehen, wie die Magie passiert.
Der einzige Unterschied zwischen etwas über eine Schale ausgeführt und direkt, dass Sie die fancy stuff auf alle Ihre Shell für Sie tun verlieren, wie variable Expansion, ausführbare usw.
Wie denkst du, dass die Shell selbst einen externen Befehl aufruft, nachdem sie die Kommandozeile geparst hat? Es * muss * eine Schnittstelle auf Betriebssystemebene sein, die es aufrufen kann. (Auch der Pass-a-String-to-a-Shell-Ansatz weist erhebliche Sicherheitsmängel auf. Shell-Injection-Schwachstellen lassen sich leicht vermeiden, wenn Sie Argumente außerhalb der Bandbreite entweder in der Umgebung oder an anderen Argv-Positionen übergeben System (string_to_parse) 'bietet keine bequeme Möglichkeit, beides zu tun. –