popen 实用实战

popen 实用实战popen和system都可以执行外部命令。popen相当于是先创建一个管道,fork,关闭管道的一端,执行exec,返回一个标准的io文件指针。system相当于是先后调用了fork,exec,waitpid来执行外部命令popen本身是不阻塞的,要通过标准io的读取使它阻塞system

大家好,欢迎来到IT知识分享网。popen

popen和system都可以执行外部命令。
popen相当于是先创建一个管道,fork,关闭管道的一端,执行exec,返回一个标准的io文件指针。
system相当于是先后调用了fork, exec,waitpid来执行外部命令
popen本身是不阻塞的,要通过标准io的读取使它阻塞
system本身就是阻塞的。

最近写的程序,要求进程在调用的外部命令运行完毕之后,再继续 向下进行。
一开始调用的popen,然后只是用了fgetc,使其阻塞,但是总是阻塞不了。原因就是如果外部命令有很多的输出内容,那fgets在得到输出的第一个字符的时候就返回了,不在阻塞了;调用fread,如果size和nitems设置的不够大,也是一样的问题。比如外部命令要输出100个字符,结果size是sizeof(char),nitems是10,那么当fread读到地10个字符的时候,就已经满足条件了,就返回了。
正确的方法是调用system,因为system最后会调用waitpid,来等待子进程运行完毕。
其实可以调用pclose来阻塞
 
下面看一下代码示例:
test_log:
#include <stdio.h>
#include<string.h>
#include <unistd.h>

int main(void)
{
    int t = 20;
    while(t-- > 0) {
        sleep(1);
        fprintf(stdout, "run test log %d\n", t);
        fflush(stdout); //这里不flush的话,popen可能无法实时读到这里输出的内容
    }
    return 0;
}

popen使用示例:
int main(void)
{
    char buf[LOG_MAX_PER_LEN];
    FILE* fp = popen("test_log", "r");
    if(fp) {
        printf("open success\n");
        while(fgets(buf, LOG_MAX_PER_LEN, fp) != NULL) {
            if(buf[strlen(buf) - 1] == '\n') {
                buf[strlen(buf) - 1] = '\0';
            }
            fprintf(stdout, "[test log output]: %s\n", buf);
        }
    } else {
        perror("popen fail!\n");
        return -1;
    }

    int ret = pclose(fp);
    printf("pclose ret %d\n", ret);
    return 0;
}

 

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/30537.html

(0)

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信