2009-02-04 7 views
5

Angenommen, es gibt einige Funktionen, die für eine Anwendung in der Entwicklung benötigt werden, die erreicht werden kann, indem ein Systemaufruf entweder zu einem Befehlszeilenprogramm oder unter Verwendung einer Bibliothek ausgeführt wird. Unter der Annahme, dass Effizienz kein Problem ist, ist es eine schlechte Praxis, einfach einen Systemaufruf an ein Programm zu senden, anstatt eine Bibliothek zu verwenden? Was sind die Nachteile, dies zu tun?Ist es eine schlechte Übung, die Funktion system() zu verwenden, wenn stattdessen Bibliotheksfunktionen verwendet werden könnten? Warum?

Um ein konkreteres Beispiel zu geben, wäre ein Beispiel dieses Szenarios eine Anwendung, die eine Datei von einem Webserver herunterladen muss, entweder das Programm cURL oder die Bibliothek libcURL.

Antwort

10

Wenn Sie nicht nur Code für ein Betriebssystem schreiben, können Sie nicht feststellen, ob Ihr Systemanruf überhaupt funktioniert. Was passiert, wenn ein Systemupdate oder ein Betriebssystemupgrade durchgeführt wird?
Nie Verwenden Sie einen Systemaufruf, wenn eine Bibliothek die gleiche Funktion ausführt.

+2

Genau das Abends ging ich ein paar kleine Perl-Dienstprogramme von mir durch und ersetzte mit einem Systemaufruf den Kopierbefehl mit File :: Copy - die neue Version ist kürzer und funktioniert auf allen meinen Plattformen statt nur auf Windows. – Sol

2

Sicherheit ist ein Anliegen. Eine bösartige cURL könnte in Ihrem Programm Verwüstungen verursachen. Es hängt davon ab, ob es sich um ein persönliches Programm handelt, bei dem die Kodierungsgeschwindigkeit im Vordergrund steht, oder um eine kommerzielle Anwendung, bei der Dinge wie Sicherheit eine Rolle spielen.

3

Ich bevorzuge Bibliotheken wegen der Abhängigkeitsproblem, nämlich die ausführbare Datei möglicherweise nicht da sein, wenn Sie es aufrufen, aber die Bibliothek wird (vorausgesetzt, externe Bibliotheksreferenzen werden kümmert sich, wenn der Prozess auf Ihrer Plattform startet). Mit anderen Worten, die Verwendung von Bibliotheken scheint in mehr Umgebungen ein stabileres und vorhersehbareres Ergebnis zu garantieren als Systemaufrufe.

3

Es gibt mehrere Faktoren, die berücksichtigt werden müssen. Ein Schlüssel ist die Zuverlässigkeit, ob das externe Programm auf allen Systemen vorhanden ist, auf denen Ihre Software installiert ist. Wenn es eine Möglichkeit gibt, dass es fehlen wird, dann ist es vielleicht besser, es in Ihrem Programm zu tun.

Wiegt man dagegen, dass der zusätzliche Code, der in Ihr Programm geladen wird, unerschwinglich ist - Sie brauchen den Code Bloat für solch einen selten verwendeten Teil Ihrer Anwendung nicht.

Die Funktion system() ist praktisch, aber gefährlich, nicht zuletzt weil sie normalerweise eine Shell aufruft. Sie können besser das Programm direkter aufrufen - auf Unix, über die Systemaufrufe fork() und exec(). [Beachten Sie, dass ein Systemaufruf sich sehr von dem Aufruf der system() Funktion unterscheidet!] OTOH, Sie müssen sich vielleicht darum sorgen, dass alle offenen Dateideskriptoren in Ihrem Programm geschlossen sind - besonders, wenn Ihr Programm eine Art Daemon ist, der im Auftrag läuft andere Benutzer; Das ist weniger ein Problem, wenn Sie keine speziellen Privilegien verwenden, aber es ist immer noch eine gute Idee, dem aufgerufenen Programm nicht auf etwas zuzugreifen, was Sie nicht vorhatten. Möglicherweise müssen Sie sich den Systemaufruf fcntl() und das Flag FD_CLOEXEC ansehen.

Im Allgemeinen ist es einfacher, die Kontrolle über die Dinge zu behalten, wenn Sie die Funktionalität in Ihr Programm einbauen, aber es ist keine triviale Entscheidung.

1

Systemanrufe sind viel schwieriger sicher herzustellen.

Alle Arten von lustigen Zeichen müssen korrekt codiert werden, um Argumente übergeben zu können, und die Arten der Codierung können je nach Plattform oder Version des Befehls variieren. Wenn Sie also einen Systemaufruf durchführen, der überhaupt Benutzerdaten enthält, müssen Sie eine Reihe von Plausibilitätsprüfungen durchführen, und es ist leicht, einen Fehler zu machen.

1

Ja, wie oben erwähnt, beachten Sie den Unterschied zwischen Systemaufrufen (wie fcntl() und open()) und System() -Aufrufen.:)

In den frühen Phasen des Prototyping ein c-Programm, mache ich oft externe Aufrufe an Programme wie Grep und Sed für die Manipulation von Dateien mit popen(). Es ist nicht sicher, es ist nicht sicher und es ist sicher nicht tragbar. Aber es kann dir erlauben, schnell loszulegen. Das ist wertvoll für mich. Es erlaubt mir, mich auf den wirklich wichtigen Kern des Programms zu konzentrieren, normalerweise den Grund, warum ich c überhaupt benutzt habe.

In High-Level-Sprachen, haben Sie besser einen guten Grund. :)

0

Anstatt dies zu tun, würde ich es Unix und erstellen Sie ein Skript-Framework um Ihre App mit den Befehlszeilenargumente und Stdin.

0

Andere haben gute Punkte erwähnt (Zuverlässigkeit, Sicherheit, Sicherheit, Portabilität, etc.) - aber ich werde einen anderen werfen. Performance. Im Allgemeinen ist es um ein Vielfaches schneller, eine Bibliotheksfunktion aufzurufen oder gar einen neuen Thread zu erzeugen, als einen kompletten neuen Prozess zu starten (und dann noch die Ausführung zu überprüfen und zu überprüfen!)