所以,你來到這裡是因為每個人都在告訴你像
system("PAUSE")
和
system("CLS")
這樣的東西很糟糕。但沒有人真正解釋
為什麼。
原因如下。
----------------- 它資源消耗大 ----------------
首先,你必須考慮
system() 函式實際上做了什麼:它執行的不僅僅是一個,而是可能
兩個獨立的程序,並將退出狀態返回給你的程式(希望是你想執行的那個程式的退出狀態)。
http://linux.die.net/man/3/system 注意所有可能出錯的地方……以及用於錯誤識別和處理的極少選擇。
但等等,還有更多!說到 system("PAUSE"),這裡是
WaltP 對 system() 為實現其目標所做工作的簡化但完整的分解。
http://www.gidnetwork.com/b-61.html
----------------- 它破壞了安全性 -----------------
那麼,如果它只是資源消耗大,又是什麼讓它如此邪惡呢?
因為你無法保證你正在執行的程式
1 是一個有效的命令
2 在所有系統上執行相同的操作
3 沒有被惡意程式碼感染,或者
4 是你認為它是什麼程式
最後兩點需要稍作解釋。
這裡有一個小的控制檯程式可以嘗試
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
#include <stdio.h>
#include <stdlib.h>
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) || defined(__WINDOWS__)
#define EDITOR "notepad"
#else
#define EDITOR "emacs"
#endif
int main()
{
printf( "Now I'm going to start your text editor!\n" );
system( EDITOR );
printf( "Good-bye!\n" );
return 0;
}
|
給 Unix/Linux 使用者的一些說明
- 我沒有安裝 emacs(我受不了它)。我用“kate”和“vim”代替。如果你沒有安裝 Emacs,請編輯上面的原始碼,將其替換為你喜歡的文字編輯器的名稱。
- 如果你不知道如何退出 emacs,請按
Ctrl-X,然後
Ctrl-C.
- 在執行你的程式之前,你必須確保 PATH 包含了當前目錄。對於 bash 使用者,在執行程式之前,在命令提示符下鍵入
ECHO=.:"$PATH"
。別擔心,這只是臨時的。一旦你完成了這些練習,鍵入一個點然後按 ENTER 鍵即可重新啟動 bash 並恢復到正確的預設設定。
好了,去編譯並執行它看看效果吧。
現在你已經看到它正常工作了,在同一個目錄下建立一個新的小程式
1 2 3 4 5 6 7
|
#include <stdio.h>
int main()
{
printf( "Bwah, hah, hah, hah, hah!\n" );
return 0;
}
|
編譯它,並將可執行檔案命名為“
notepad.exe”(如果你在 Windows 上),或者“
emacs”(或者上面你使用的任何名稱),如果你在 *nix 上。(小心不要覆蓋你第一個程式的*.exe)。
現在再次執行第一個程式。發生了什麼?(Unix/Linux 使用者,現在是重啟 shell 的好時機。記住,這個例子是人為設計的——有很多其他方法可以將惡意軟體引入執行路徑。)
危險在於,當你直接執行一個程式時,它會獲得與你的程式相同的
許可權——這意味著,例如,如果你以系統管理員的身份執行,那麼你剛剛無意中執行的惡意程式
也將以系統管理員的身份執行。如果這還不能讓你嚇得魂飛魄散,請檢查一下你的脈搏。
即使你不是 sysadmin 也沒關係。
你能做的
它都能做。
------------- 反病毒程式討厭它 -------------
最後一件事僅僅是感知問題。如果你的使用者執行任何型別的防毒軟體,如 ZoneAlarm、Norton、McAfee 等,那麼他們就會收到一條非常令人不快的訊息,說你的程式試圖做一些被認為危險的事情。請記住,防毒軟體不會說明你試圖做什麼,只說明它試圖做一些不當的事情。使用者對這類程式持懷疑態度。
好了,就到這裡吧。除非必要,否則不要使用
system()。
希望這有幫助。
作為補充,如果你
確實需要使用
system(),通常最好檢查一下你是否有一個 shell 可用。
1 2
|
if (system( NULL )) then_I_can_safely_use_system();
else fooey();
|
另外,直接來自手冊頁
不要在具有 set-user-ID 或 set-group-ID 許可權的程式中使用 system(),因為某些環境變數的奇怪值可能會被用來破壞系統完整性。請使用 exec(3) 系列函式,但不要使用 execlp(3) 或 execvp(3)。在某些系統上,如果 /bin/sh 是 bash 2 版本,並且 bash 2 在啟動時會降權,那麼 system() 在具有 set-user-ID 或 set-group-ID 許可權的程式中實際上將無法正常工作。(Debian 使用了一個修改過的 bash,在被呼叫為 sh 時不會這樣做。)
盡情享受吧!