Warum ist lsfür die Ausführung ein separater Prozess erforderlich? Ich kenne den Grund, warum Befehle wie cdnicht mit dem Gabelmechanismus ausgeführt werden können, aber kann es schaden, wenn lssie ohne Gabeln ausgeführt werden?
Warum ist lsfür die Ausführung ein separater Prozess erforderlich? Ich kenne den Grund, warum Befehle wie cdnicht mit dem Gabelmechanismus ausgeführt werden können, aber kann es schaden, wenn lssie ohne Gabeln ausgeführt werden?
Antworten:
Die Antwort ist mehr oder weniger lseine externe ausführbare Datei. Sie können die Position anzeigen, indem Sie ausführen type -p ls.
Warum ist lsdie Shell dann nicht eingebaut? Nun, warum sollte es sein? Die Aufgabe einer Shell besteht nicht darin, jeden verfügbaren Befehl zu umfassen, sondern eine Umgebung bereitzustellen, in der sie ausgeführt werden kann. Einige moderne Schalen haben echo, printfund Konsorten als builtins, die nicht technisch builtins sein müssen, sind aber so aus Performance - Gründen gemacht , wenn sie wiederholt ausgeführt werden (vor allem in engen Schleifen). Ohne sie zu integrieren, müsste die Shell für jeden Aufruf einen neuen Prozess ausgeben und ausführen, was extrem langsam sein kann.
Um lseine externe ausführbare Datei auszuführen, muss mindestens eine der Systemaufrufe der exec-Familie ausgeführt werden. Sie könnten dies ohne Gabeln tun, aber es würde die primäre Shell ersetzen, die Sie verwenden. Sie können sehen, was in dieser Instanz passiert, indem Sie wie folgt vorgehen:
exec ls; echo "this never gets printed"
Da das Prozessabbild Ihrer Shell ersetzt wird, ist die aktuelle Shell danach nicht mehr erreichbar. Damit die Shell nach dem Ausführen von ls weiter ausgeführt werden kann, muss der Befehl in die Shell integriert werden.
Durch das Verzweigen kann ein Prozess ersetzt werden, der nicht Ihre primäre Shell ist, sodass Sie Ihre Shell anschließend weiter ausführen können.
echo, printfusw.
cdkeine externe ausführbare Datei?
cdausführbare Datei vorhanden ( siehe hier ). Wenn Sie jedoch tatsächlich chdir () im aktuellen Prozess verwenden möchten, müssen Sie es in die Shell integrieren.
Im Bash-Referenzhandbuch heißt es:
Integrierte Befehle sind erforderlich, um Funktionen zu implementieren, die mit separaten Dienstprogrammen nicht oder nur schwer zu erhalten sind.
Das heißt, Shells enthalten nur dann eingebaute Befehle, wenn:
Der lsBefehl entspricht keiner der oben genannten Anforderungen.
Allerdings , hier ist keine Programmierung Einschränkung , die verhindern würde lsals Einbau in wobei implmented, die sich im selben Prozess wie der Bash - Interpreter ausgeführt wird . Die Entwurfsgründe für Befehle, die nicht als Shell-Einbauten implementiert werden, sind:
Zum ersten Grund: Sie möchten, dass die Shell so unabhängig und widerstandsfähig wie möglich ist. Sie möchten nicht, dass die Shell an lseinem NFS-Mount hängen bleibt, der "immer noch nicht antwortet".
Zum zweiten Grund: In vielen Fällen möchten Sie möglicherweise eine Shell für ein System verwenden, das Busybox oder ein anderes Dateisystem mit einer anderen lsImplementierung verwendet. Oder verwenden Sie in Betriebssystemen mit unterschiedlichen lsImplementierungen dieselbe Shell-Quelle .
Zum dritten Grund - Für Ausdrücke wie find . -type d | xargs ls -ladwäre es schwierig oder unmöglich, die lsim gleichen Prozess wie der Shell-Interpreter zu implementieren .
Zum vierten Grund - Die lsAusführung einiger Befehle kann einige Zeit in Anspruch nehmen. Vielleicht möchten Sie, dass die Shell in der Zwischenzeit noch etwas anderes ausführt.
Hinweis: Siehe diesen hilfreichen Beitrag von Warren Young als Antwort auf eine ähnliche Frage.
lsin einen externen Prozess umleiten müsste . Es könnte getan werden, aber es wäre kompliziert.
bashAusgabe alias | grep ls. Eingabecat /etc/passwd | while read a; do echo "$a"; done
lserfordert keinen separaten Prozess. Nur sehr wenige Befehle erfordern einen separaten Prozess: Nur diejenigen, die Berechtigungen ändern müssen.
In der Regel implementieren Shells Befehle nur dann als integrierte Befehle, wenn diese Befehle als integrierte Befehle implementiert werden müssen. Befehle wie alias, cd, exit, export, jobs, ... muß einigen internen Zustand der Schale lesen oder zu ändern, und kann daher nicht getrennte Programme sein. Befehle ohne solche Anforderungen können separate Befehle sein. Auf diese Weise können sie von jeder Shell oder einem anderen Programm aus aufgerufen werden.
Betrachtet man die Liste der Buildins in Bash, so können nur die folgenden Buildins als separate Befehle implementiert werden. Für einige von ihnen würde es einen leichten Funktionsverlust geben.
command- aber es würde seine Nützlichkeit in Situationen verlieren, in denen es PATHmöglicherweise nicht richtig eingerichtet ist und das Skript es commandals Teil der Einrichtung verwendet.echo - Es ist ein fester Bestandteil der Effizienz.help - Es könnte eine separate Datenbank verwendet werden, aber das Einbetten des Hilfetexts in die ausführbare Shell-Datei hat den Vorteil, dass die ausführbare Shell in sich geschlossen ist.kill - Ein integrierter Prozess bietet zwei Vorteile: Er kann neben Prozess-IDs auch Job-Bezeichnungen erkennen und verwendet werden, selbst wenn nicht genügend Ressourcen zum Starten eines separaten Prozesses vorhanden sind.printf- Aus dem gleichen Grund wie echound um die -vOption zu unterstützen, die Ausgabe in eine Variable zu setzen.pwd - Das eingebaute Modul bietet die zusätzliche Möglichkeit, das aktuelle Verzeichnis logisch zu verfolgen (wobei symbolische Verknüpfungen intakt bleiben, anstatt sie zu erweitern).test- Es ist aus Effizienzgründen eingebaut (und Bash macht auch etwas Magie mit Dateien, die /dev/fd/…auf einigen Betriebssystemen aufgerufen werden).Einige wenige Muscheln bieten eine erhebliche Anzahl zusätzlicher eingebauter Komponenten. Es gibt Sash , eine Shell, die als eigenständige Binärdatei für Notfallreparaturen entwickelt wurde (wenn einige externe Befehle möglicherweise nicht verwendet werden können). Es hat ein eingebautes ls, genanntes -ls, sowie andere Tools wie -grepund -tar. Die eingebauten Funktionen von Sash sind weniger leistungsfähig als die vollwertigen Befehle. Zsh bietet einige ähnliche integrierte Funktionen in seinem Modul zsh / files an . Es hat keine ls, aber Wildcard-Erweiterung ( echo *) und zstatkann eine ähnliche Funktion erfüllen.
Ich denke, dass hier etwas fehlt, was die Scherkomplexität des GNU- lsProgramms unter Linux ist. Vergleicht man die ausführbare Größe von lsmit bashund dashShells auf meinem Debian-System, so sieht man, dass es ziemlich groß ist:
graeme@graeme:~$ ls -lh /bin/{ls,bash,dash}
-rwxr-xr-x 1 root root 953K Mar 30 2013 /bin/bash
-rwxr-xr-x 1 root root 115K Dec 25 20:25 /bin/dash
-rwxr-xr-x 1 root root 108K Jul 20 22:52 /bin/ls
Das Einbeziehen einer lsso umfassenden Version wie die GNU-Version in bashwürde die ausführbare Größe um 10% erhöhen. Es ist fast so groß wie die ganze dashSchale!
Die meisten Shell-Buildins werden ausgewählt, weil sie sich so in die Shell integrieren lassen, wie es externe ausführbare Dateien nicht können (die Frage zeigt cd, aber ein anderes Beispiel ist die Bash-Version der killIntegration in die Bash-Job-Steuerung) oder weil sie sehr einfach zu implementierende Befehle sind. eine große Geschwindigkeit gegen Größe auszahlen ( trueund falsesind so einfach wie es nur geht).
GNU lshatte einen langen Entwicklungszyklus und implementiert möglicherweise Optionen, um anzupassen, welche / wie Ergebnisse angezeigt werden. Die Verwendung eines integrierten Betriebssystems würde entweder diese Funktionalität verlieren oder die Komplexität und Größe der Shell erheblich erhöhen.
Das tun, wonach Sie suchen:
printf "%s\n" *
Sie können auch Dateinamen im Array speichern:
files=(`printf "%s\n" *`) #items are separated by whitespace
echo ${#files[*]} files
for index in ${!a[*]}
do printf "%d: %s\n" $index ${a[$index]};
done
Leerzeichen in Namen sind ihm jedoch egal.
Dies wird an Variable übergeben und Leerzeichen sind wichtig:
printf "%s\n" * | while read a; do echo $a; done
lses sich um ein externes Programm handelt,echo *oderecho * .*(abhängig von den Shell-Optionen) Dateien ziemlich gut auflistet, ohne zu forken.