假設我們要将一個檔案的資料,通過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,建立了一個過濾程式, 主程式給螢幕輸出提示, 我們從螢幕輸入一行字元串,字元串傳給過濾程式,過濾程式處理後發送給主程式,主程式輸出
注意要經常洗刷緩沖區,即把他輸出出來。