码迷,mamicode.com
首页 > 系统相关 > 详细

执行shell命令的函数——system()、popen()

时间:2017-07-24 09:56:38      阅读:189      评论:0      收藏:0      [点我收藏+]

标签:system、popen

1、FILE* popen(const char* cmd,const char* type);

    int pclose(FILE* stream);

    popen()函数fork()一个子进程,创建管道用于父子进程间通信,父进程要么从管道读,要么往管道写,执行一个shell以运行命令来开启一个进程

    相比于system()的又是在于使用简单,popen()只返回两个值,成功返回子进程的status,失败返回-1



2、int system(const char* cmd);

    处理了fork()、execl()、waitpid()这些细节,还有一些信号


    1、这个库函数使用fork()创建一个子进程来;

    2、子进程调用/bin/sh-c cmd执行指定的参数命令(/bin/sh一般是一个软连接,指向某个具体的shell,比如bash,-c选项告诉shell从字符串cmd中读取命令),执行完之后返回调用原进程;

    3、父进程调用waitpid等待子进程结束。

    执行命令时SIGCHLD将被阻塞,在调用system()的进程中SIGINT和SIGQUIT将被忽略。


    返回值:

    如果cmd是NULL,返回非0,一般为1;

    如果fork()失败,即子进程无法被创建,返回-1;

    如果shell在子进程中不能被替换,即execl()失败,返回127;

    如果所有系统调用成功了,子进程执行cmd命令,但cmd命令不一定执行成功,返回cmd通过exit或return返回的值;


    system()源码:

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()会继承环境变量,编写具有SUID/SGID权限的程序时不要用这个函数

 建议system()只用来执行shell命令

 建议监控一下system()函数执行完毕之后的errno值

 建议使用popen()代替system()



http://blog.sina.com.cn/s/blog_8043547601017qk0.html


《完》

本文出自 “零蛋蛋” 博客,谢绝转载!

执行shell命令的函数——system()、popen()

标签:system、popen

原文地址:http://lingdandan.blog.51cto.com/10697032/1950285

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!