1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > popen+pclose 执行 shell 命令

popen+pclose 执行 shell 命令

时间:2020-01-02 01:18:19

相关推荐

popen+pclose 执行 shell 命令

在《system() 执行 shell 命令》中,我们介绍了 system 执行 shell 命令的方法,system 返回值比较混乱,难以理解,而且 popen 在处理子进程标准输出上会很方便。

注意:管道只能处理标准输出,不能处理标准错误输出。

popen 和 pclose 的实现与 system 类似,多了一步创建管道的操作。

popen 成功返回 FILE 句柄,失败返回 NULL, 失败的原因可能为 fork 或 pipe 失败,也可能为分配内存失败;

pclose 失败返回 -1, 成功则返回 exit status, 同 system 类似,需要用WIFEXITED,WEXITSTATUS 等获取命令返回值。

此外,同 system 类似, pclose 会等待进程退出,如果等不到进程退出(例如已经被 wait 回收),则 error 设置为ECHILD.

注意:

1. pclose 仅仅是为了回收子进程,避免僵尸进程的产生;

2. 和 system 一样,SIGCHLD 依然会影响 popen,见示例程序。

[cpp]view plaincopy

#include<stdio.h>

#include<errno.h>

#include<stdlib.h>

#include<string.h>

#include<signal.h>

typedefvoid(*sighandler_t)(int);

intmain(intargc,char*argv[])

{

charcmd[1024];

charline[1024];

FILE*pipe;

intrv;

if(argc!=2)

{

printf("Usage:%s<path>\n",argv[0]);

return-1;

}

//pclosefail:Nochildprocesses

signal(SIGCHLD,SIG_IGN);

snprintf(cmd,sizeof(cmd),"ls-l%s2>/dev/null",argv[1]);

//sighandler_told_sighandler=signal(SIGCHLD,SIG_DFL);

pipe=popen(cmd,"r");

if(NULL==pipe)

{

printf("popen()failed:%s\n",cmd);

return-1;

}

while(fgets(line,sizeof(line),pipe)!=NULL)

{

printf("%s",line);

}

rv=pclose(pipe);

//signal(SIGCHLD,old_sighandler);

if(-1==rv)

{

printf("pclose()failed:%s\n",strerror(errno));

return-1;

}

if(WIFEXITED(rv))

{

printf("subprocessexited,exitcode:%d\n",WEXITSTATUS(rv));

if(0==WEXITSTATUS(rv))

{

//ifcommandreturning0meanssucceed

printf("commandsucceed\n");

}

else

{

if(127==WEXITSTATUS(rv))

{

printf("commandnotfound\n");

returnWEXITSTATUS(rv);

}

else

{

printf("commandfailed:%s\n",strerror(WEXITSTATUS(rv)));

returnWEXITSTATUS(rv);

}

}

}

else

{

printf("subprocessexitfailed\n");

return-1;

}

return0;

}

说明:

1. 将 SIGCHLD 忽略之后,pclose 不能回收子进程退出信息,errno 为ECHILD, 错误信息为 "No child processes";

2. 由于管道不能捕获 stderr, 因此命令将 stderr 重定向至 /dev/null.

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。