stdlib库有个很多人用过的函数:system. 如果希望这段代码能够跨平台,而希望让程序能等个1秒,一个很好的方法就是,system("sleep 1");这样,无论是windows还是linux,我们都可以很好的执行"等待1秒",而不必多写好多参数什么的. 但是,有时候,我们希望能够得到这个命令的输出,而不是只是"执行它".那么,我们需要点新的东西了.

管道_(Unix)即是一个由标准输入输出链接起来的进程集合,所以每一个进程的输出(stdout)被直接作为下一个进程的输入(stdin)。 每一个链接都由未命名管道实现。过滤程序经常被用于这种设置。[1] 我们可以通过一些系统提供的管道函数,获得这个输出. 这不是一个标准库函数,而是系统相关的. linux下一个比较方便的函数是 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一个线程,所以环境变量是直接复制的,权限问题什么的要注意一下.

来自的你,很高兴你能看到这儿。若本文对你有所用处,或者内容有什么不足之处,敬请毫不犹豫给个回复。谢谢!