2009-02-04 65 views
5

假設正在開發的應用程序需要某些功能,可以通過系統調用命令行程序或使用庫來實現。假設效率不是問題,簡單地對程序進行系統調用而不是使用庫是不好的做法?這樣做的缺點是什麼?當可以使用庫函數時,使用system()函數是不好的做法嗎?爲什麼?

爲了使事情更加具體,這個場景的一個例子是需要從web服務器下載文件的應用程序,可以使用cURL程序或libcURL庫。

回答

10

除非您只爲一個OS編寫代碼,否則無法知道您的系統調用是否可以正常工作。系統更新或操作系統升級時會發生什麼?
從來沒有使用系統調用,如果有一個庫來執行相同的功能。

+2

只是這個傍晚,我經歷了幾個我的小型Perl實用程序,並使用File :: Copy對系統調用複製命令進行替換 - 新版本更短,適用於所有平臺而不僅僅是Windows。 – Sol 2009-02-04 03:27:49

2

安全性是一個問題。惡意的cURL可能會對您的程序造成嚴重破壞。這取決於這是一個以編碼速度爲主要目標的個人程序,還是一個安全性等因素影響的商業應用程序。

3

由於存在依賴性問題,我更喜歡使用庫,也就是說,當您調用它時,可執行文件可能不在那裏,但庫會(假設在您的平臺上啓動時啓動外部庫引用)。換句話說,使用庫似乎可以在比系統調用更多的環境中保證更穩定,更可預測的結果。

3

有幾個因素需要考慮。其中一個關鍵是外部程序是否會出現在安裝軟件的所有系統上。如果有可能會丟失它,那麼最好在程序中執行它。

稱重於此,您可能會認爲將額外的代碼加載到您的程序中是令人望而卻步的 - 您不需要爲應用程序中很少使用的部分添加代碼。

system()函數很方便,但很危險,通常是因爲它調用一個shell。在Unix上,通過fork()和exec()系統調用可以更直接地調用程序。 [請注意,系統調用與調用system()函數非常不同!] OTOH,您可能需要擔心確保程序中的所有打開的文件描述符都關閉 - 特別是如果您的程序是某種代表其他用戶;如果你沒有使用特殊權限,那麼這個問題就不那麼嚴重了,但是不要讓被調用的程序訪問任何你不想要的東西,這仍然是一個好主意。您可能需要查看fcntl()系統調用和FD_CLOEXEC標誌。

通常,如果將功能構建到程序中,則更容易控制事情,但這不是一個微不足道的決定。

1

系統調用難以安全進行。

各種有趣的字符需要正確編碼以傳遞參數,並且編碼類型可能因平臺或甚至版本的命令而異。因此,做一個包含任何用戶數據的系統調用都需要很多的理智檢查,並且很容易犯一個錯誤。

1

是的,如上所述,請記住系統調用(如fcntl()和open())和system()調用之間的區別。:)

在原型的c程序的早期階段,我經常使用popen()來調用像grep和sed這樣的程序來處理文件。這並不安全,不安全,而且當然不是便攜式的。但它可以讓你快速起步。這對我很有價值。它讓我專注於程序真正重要的核心,通常是我首先使用c的原因。

在高級語言中,最好有一個很好的理由。 :)

0

而不是做任何一個,我會把它Unix,並使用命令行參數和標準輸入在您的應用程序周圍構建一個腳本框架。

0

其他人提到的好點(可靠性,安全性,安全性,便攜性等) - 但我會拋出另一個。性能。一般來說,調用一個庫函數甚至產生一個新線程會快很多倍,然後開始一個新的進程(然後你仍然必須正確地檢查/驗證它的執行並解析它的輸出!)

相關問題