先来看一下system()函数的简单介绍:linux
#include int system(const char *command)
system()函数调用/bin/sh来执行参数指定的命令,/bin/sh 通常是一个软链接,指向某个具体的shell,好比bash,-c选项是告诉shell从字符串command中读取命令; 在该command执行期间,SIGCHLD是被阻塞的,比如在说:hi,内核,这会不要给我送SIGCHLD信号,等我忙完再说; 在该command执行期间,SIGINT和SIGQUIT是被忽略的,意思是进程收到这两个信号后没有任何动做。shell
再来看一下system()函数返回值:bash
为了更好的理解system()函数返回值,须要了解其执行过程,实际上system()函数执行了三步操做:函数
看一下system()函数的源码测试
看完这些,我想确定有人对system()函数返回值仍是不清楚,看源码最清楚,下面给出一个system()函数的实现:debug
int system(const char * cmdstring) { pid_t pid; int status; if(cmdstring == NULL) { return (1); //若是cmdstring为空,返回非零值,通常为1 } if((pid = fork())<0) { status = -1; //fork失败,返回-1 } else if(pid == 0) { execl("/bin/sh", "sh", "-c", cmdstring, (char *)0); _exit(127); // exec执行失败返回127,注意exec只在失败时才返回如今的进程,成功的话如今的 进程就不存在啦~~ } else //父进程 { while(waitpid(pid, &status, 0) < 0) { if(errno != EINTR) { status = -1; //若是waitpid被信号中断,则返回-1 break; } } } return status; //若是waitpid成功,则返回子进程的返回状态 }
仔细看完这个system()函数的简单实现,那么该函数的返回值就清晰了吧,那么何时system()函数返回0呢?只在command命令返回0时。指针
看一下该怎么监控system()函数执行状态 这里给我出的作法:orm
int status; if(NULL == cmdstring) //若是cmdstring为空趁早闪退吧,尽管system()函数也能处理空指针 { return XXX; } status = system(cmdstring); if(status < 0) { printf("cmd: %s\t error: %s", cmdstring, strerror(errno)); // 这里务必要把errno信息输出或 记入Log return XXX; } if(WIFEXITED(status)) { printf("normal termination, exit status = %d\n", WEXITSTATUS(status)); //取得cmdstring执行结果 } else if(WIFSIGNALED(status)) { printf("abnormal termination,signal number =%d\n", WTERMSIG(status)); //若是cmdstring被信号中 断,取得信号值 } else if(WIFSTOPPED(status)) { printf("process stopped, signal number =%d\n", WSTOPSIG(status)); //若是cmdstring被信号暂停执 行,取得信号值 }
system()函数用起来很容易出错,返回值太多,并且返回值很容易跟command的返回值混淆。这里推荐使用popen()函数替代,关于popen()函数的简单使用能够本身查下资料。教程
popen()函数较于system()函数的优点在于使用简单,popen()函数只返回两个值: 成功返回子进程的status,使用WIFEXITED相关宏就能够取得command的返回结果; 失败返回-1,咱们可使用perro()函数或strerror()函数获得有用的错误信息。进程
这篇文章只涉及了system()函数的简单使用,尚未谈及SIGCHLD、SIGINT和SIGQUIT对system()函数的影响,事实上,之因此今天写这篇文章,是由于项目中因有人使用了system()函数而形成了很严重的事故。现像是system()函数执行时会产生一个错误:“No child processes”。此时调用my_system()来执行system函数的功能(my_system函数中是使用popen()函数来实现的), 测试了一天,没有再次出现程序忽然死掉的问题(修改前连续循环调用system()函数测试,每10次就会至少致使程序挂掉一次.连续不停顿的调用)。
免费提供最新Linux技术教程书籍,为开源技术爱好者努力作得更多更好:http://www.linuxprobe.com/