程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 《精通Unix下C語言編程與項目實踐》之七——標准I/O重定向

《精通Unix下C語言編程與項目實踐》之七——標准I/O重定向

編輯:關於C語言

文章試讀 不拘一個遍程序系列編程序不能一個腦袋鑽到底,有時要學會變通,即所謂的曲線救國。 職場規劃:一些雜七雜八的職場感悟吧。不值錢的軟件人才 精力充沛與事業成功   讓系分來得更猛烈些吧    不值錢的系統分析師  我的詩歌:都是我的打油詩,但是很值得一讀。不要工作還衣食無憂之四難歌   香格裡拉美人圖 寶寶圖片:超可愛的小寶寶 博客 考試培訓:主要是關於考研、軟考和等級的相關題解。2009考研試題分析   2008年12月程序員試題分析    2009年軟考備考全攻略    2008年5月程序員試題解析       《精通Unix下C語言編程與項目實踐》之七 標准I/O重定向  作者:朱雲翔,胡平

11.2.4 連接標准I/O的管道模型

管道在shell中最常見的應用是連接不同進程的輸入輸出,比如使A進程的輸出變成B進程的輸入等。考察shell命令“cat pipe3.c | more”,進程“more”使用了進程“cat pipe3.c”的輸出。 例1. 分別重定向標准輸入、標准輸出、標准錯誤輸出到文件描述符fd1、fd2和fd3中。 答:復制文件描述符fd1到文件描述符0中即可重定向標准輸入,其它的類似,如以下語句所示: dup2(fd1, 0);   /* 復制fd1到文件描述符0中,更改標准輸入為fd1 */ dup2(fd2, 1);   /* 復制fd2到文件描述符1中,更改標准輸出為fd2 */ dup2(fd3, 2);   /* 復制fd3到文件描述符2中,更改標准錯誤輸出為fd3 */ 當執行“dup2(fd1, 0)”後,文件描述符0就對應到了fd1所對應的文件中,而一些標准輸出函數,如printf、puts等仍然向描述符0中寫入內容,從而達到了重定向的效果。

模型

使用管道將父進程標准輸入連接到子進程標准輸入的方法如下: (1) 創建管道,返回無名管道的兩個文件描述符fildes[0]和fildes[1]。 (2) 創建子進程,子進程中繼承無名管道文件描述符。 (3) 父進程關閉管道的輸出端,即關閉只讀文件描述符fileds[0]。 (4) 父進程將標准輸出stdout,文件描述符1)重定向為文件描述符fileds[1]。 (5) 子進程關閉管道的輸入端,即關閉只寫文件描述符fileds[1]。 (6) 子進程將標准輸入stdin,文件描述符0)重定向為文件描述符fileds[0]。 最終創建的管道流如圖11-7所示: 圖11-7 父子進程標准I/O管道父進程流向子進程)

實例

本處設計一個將父進程標准輸出流連接到子進程標准輸入流的管道,父進程向stdout輸出的“Hello!”直接轉移到子進程的stdin,由子進程“gets(buf)”語句所獲取。如代碼11-6所示: 代碼11-6 父進程的輸出連接子進程的輸入通信實例節自/code/chapter11/pipe3.c) #include <unistd.h> #include <stdio.h> int main() {     int fildes[2];     pid_t pid;     int i, j;     char buf[256];     if (pipe(fildes) < 0 || (pid = fork()) < 0) /* 創建管道和子進程 */     {         fprintf(stderr, "error!\n");         return 1;     }     if (pid == 0)     {     /* ―――――――――――――――――子進程―――――――――――――――――― */         close(fildes[1]);                           dup2(fildes[0], 0);                 /* 重定向stdin到fildes[0]中 */         close(fildes[0]);         gets(buf);                          /* 讀入輸入,其實是讀取父進程輸出 */         fprintf(stderr, "child:[%s]\n", buf);         return 2;     }     /* ―――――――――――――――――父進程―――――――――――――――――― */     close(fildes[0]);     dup2(fildes[1], 1);                     /* 重定向stdout到fildes[1]中 */     close(fildes[1]);     puts("Hello!");                         /* 輸出,同時增加子進程的輸入信息*/     return 0;                           } 編譯與運行代碼11-6: # make pipe3         cc -O -o pipe3 pipe3.c # ./pipe3 child:[Hello!] 上例中,父進程的標准輸出已經重定向到管道中,故父進程puts未能將結果打印到屏幕上   相關文章: 封面          前言        目錄         策劃         作者 動態庫        變長參數    文件鎖       外設         僵死進程 定時器        I/O重定向

本文出自 “編程浪子朱雲翔” 博客,請務必保留此出處http://zhuyunxiang.blog.51cto.com/653596/134458

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved