导读 | 曾经的曾经,被system()函数折磨过,之因此这样,是由于对system()函数了解不够深刻。这里必需要搞懂system()函数,由于有时你不得不面对它。 |
#include int system(const char *command)
system()函数调用/bin/sh来执行参数指定的命令,/bin/sh 通常是一个软链接,指向某个具体的shell,好比bash,-c选项是告诉shell从字符串command中读取命令; 在该command执行期间,SIGCHLD是被阻塞的,比如在说:hi,内核,这会不要给我送SIGCHLD信号,等我忙完再说; 在该command执行期间,SIGINT和SIGQUIT是被忽略的,意思是进程收到这两个信号后没有任何动做。html
为了更好的理解system()函数返回值,须要了解其执行过程,实际上system()函数执行了三步操做:linux
看完这些,我想确定有人对system()函数返回值仍是不清楚,看源码最清楚,下面给出一个system()函数的实现:shell
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时。bash
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次就会至少致使程序挂掉一次.连续不停顿的调用)。debug
本文地址:http://www.linuxprobe.com/linux-system-constructors.html指针