所以,你来到这里是因为每个人都在告诉你像
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 时不会这样做。)
尽情享受吧!