stdlib 库有个很多人用过的函数:system.

如果希望这段代码能够跨平台,而希望让程序能等个1秒,一个很好的方法就是,system("sleep 1");这样,无论是windows还是linux,我们都可以很好的执行"等待1秒",而不必多写好多参数什么的.

但是,有时候,我们希望能够得到这个命令的输出,而不是只是"执行它".那么,我们需要点新的东西了.

管道 即是一个由标准输入输出链接起来的进程集合,所以每一个进程的输出(stdout)被直接作为下一个进程的输入(stdin)。 每一个链接都由未命名管道实现。过滤程序经常被用于这种设置。[1]

我们可以通过一些系统提供的管道函数,获得这个输出.

这不是一个标准库函数,而是系统相关的.

POSIX 下一个比较方便的函数是 popen.

popen的函数原型是:

FILE *popen(const char *command, const char *type);

manual 下的描述是

the popen() function opens a process by creating a pipe, forking, and invoking the shell. Since a pipe is by definition unidirectional, the type argument may specify only reading or writing, not both; the resulting stream is correspondingly read-only or write-only.

大意是fork出一个线程,执行然后得到结果,存储到管道文件中,返回文件只读或者只写句柄.或者失败,返回NULL.

popen的方法很简单,和fopen一样,传入两个字符串,得到一个文件句柄.只不过fopen第一个参数是文件名,而popen是命令.然后其他用法 -- 都已经得到了 FILE * 了还有什么不会的么?

windows下也有个很相似的函数,不过是函数名是_popen,我们可以简单的通过宏搞定跨平台.

扯淡完毕,代码本身其实可以简单的说明一切

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#ifndef WIN32 // headers for linux
#include <sys/types.h>
#include <unistd.h>
#endif // WIN32

#ifdef WIN32 // windows
#define _exec(cmd) _popen(cmd, "r")
#else // linux
#define _exec(cmd) popen(cmd, "r")
#endif // WIN32


int main(int argc,char *argv[])
{
    FILE *stream;
    char buf[1024];
    memset(buf,'\0',sizeof(buf));//初始化buf,以免后面写如乱码到文件中
    stream = _exec("echo \"hello, world !\""); //将参数内容命令的输出,得到管道文件句柄
    if(stream != NULL)
    {
        //将刚刚FILE* stream的数据流读取到buf中
        fread( buf, sizeof(char), sizeof(buf), stream);
        fwrite( buf, 1, sizeof(buf), stdout );//将buf中的数据写到stdout
        //关闭流
        pclose(stream);
    }else
    {
    //执行失败
        printf("error!\n");
    }
    return 0;
}

代码是使用管道执行

echo "hello, world!"

这个命令. 然后读取执行结果,输出.

一个需要注意的问题是,因为原理是fork一个线程,所以环境变量是直接复制的,权限问题什么的要注意一下.

Categories: Code

Yu

Ideals are like the stars: we never reach them, but like the mariners of the sea, we chart our course by them.

4 Comments

原创博客 · August 6, 2013 at 10:53

Google Chrome 28.0.1500.95 Google Chrome 28.0.1500.95 Windows 8 x64 Edition Windows 8 x64 Edition

很有用啊

Leniy · July 29, 2013 at 08:07

Google Chrome 28.0.1500.72 Google Chrome 28.0.1500.72 Windows 7 Windows 7

哈,rss最近20篇全部更新了

    yu · July 29, 2013 at 08:17

    Google Chrome 28.0.1500.72 Google Chrome 28.0.1500.72 Windows 7 x64 Edition Windows 7 x64 Edition

    估计是我调整了下RSS输出的原因吧

      Leniy · July 29, 2013 at 08:18

      Google Chrome 28.0.1500.72 Google Chrome 28.0.1500.72 Windows 7 Windows 7

      恩,应该了

Leave a Reply to yu Cancel reply

Your email address will not be published. Required fields are marked *