假设我们要将一个文件的数据,通过more程序来显示
但不希望建立临时文件, 即先复制整个文件,再用more来展示
我们可以把文件的数据塞入一个管道, more程序(由子进程excel启动)读这些数据,并显示在屏幕上
和直接more一个文件有啥区别???
#include "apue.h"
#include <sys/wait.h>
#define DEF_PAGER "/bin/more"
int main(int argc, char *argv[]){
int n;
int fd[2];
pid_t pid;
char *paper, *argv0;
char line[MAXLINE];
FILE *fp;
if(argc != 2)
err_quit("usage: a.out <pathname>");
if((fp = fopen(argv[1], "r")) == NULL)
err_sys("can't open %s", argv[1]);
if(pipe(fd) < 0)
err_sys("pipe error");
if((pid = fork()) < 0)
err_sys("pipe error");
else if(pid > 0){ //parent!
close(fd[0]); //关闭读管道端(即管道流向父进程的那段)
while(fgets(line, MAXLINE, fp) != NULL){
n = strlen(line);
//每次读一行,写入管道中
if(write(fd[1], line ,n) != n)
err_sys("write error to pipe");
}
if(ferror(fp))
err_sys("fgets error");
close(fd[1]);
if(waitpid(pid, NULL, 0) < 0)
err_sys("waitpid error");
exit(0);
}else {
//子进程,则关闭子进程到管道的那一端
//故子进程负责读管道
close(fd[1]);
if(fd[0] != STDIN_FILENO){
//重定向,故标准输入成为读管道端
//从apue画的图上看,描述符0和描述符fd0都指向了管道的读端
if(dup2(fd[0], STDIN_FILENO) != STDIN_FILENO){
err_sys("dup2 error to stdin");
}
//关闭fd0,则此时只有描述符0指向读管道端。
//即不再是通过fd0与管道联系,而是标准输入与管道联系
//即不再是fd0读管道,而是子进程的标准输入读管道。
close(fd[0]);
}
if((paper = getenv("PAGER")) == NULL)
paper = DEF_PAGER;
if((argv0 = strrchr(paper, '/')) != NULL)
argv0++;
else argv0 = paper;
//启用./bin/more
//此时,我们可以在终端上输入命令,传给more进程即分页读进程
execl(paper, argv0, (char *)0);
}
}
popen直接将fork和建立单向管道合并在了一起,并且支持缓冲区,即返回文件指针。
这个是大写转小写chengxu
#include "apue.h"
#include <ctype.h>
int main(int argc, char *argv[]){
int c;
while( (c = getchar() != EOF)){
if (isupper(c))
c = tolower(c);
if (putchar(c) == EOF)
err_sys("output error");
if ( c == '\n')
fflush(stdout);
}
exit(0);
}
#include "apue.h"
#include <sys/wait.h>
int main(int argc, char *argv[]){
char line[MAXLINE];
FILE *fpin;
//fork了一个子进程myuclc,且现在会读子进程的标准输出
//fpin就是可以读 那个子进程输出 的文件指针
if((fpin = popen("myuclc", "r")) == NULL)
err_sys("popen error");
for(;;){
fputs("prompt> ", stdout);
fflush(stdout); //洗刷标准输出缓冲区,即直接把prompt输出
//不断读fpin那传来的行
//那一边每读到一次'\n',就会洗刷缓冲,把一行的内容发送过来
if(fgets(line, MAXLINE, fpin) == NULL)
break;
if(fputs(line, stdout) == EOF)
err_sys("fputs error to pipe");
}
if(pclose(fpin) == -1)
err_sys("pclose error");
putchar("\n");
exit(0);
}
通过popen,建立了一个过滤程序, 主程序给屏幕输出提示, 我们从屏幕输入一行字符串,字符串传给过滤程序,过滤程序处理后发送给主程序,主程序输出
注意要经常洗刷缓冲区,即把他输出出来。