函數原型:shell
#include 「stdio.h」數組
FILE popen( const char command, const char* mode )函數
參數說明:oop
command: 是一個指向以 NULL 結束的 shell 命令字符串的指針。這行命令將被傳到 bin/sh 並使用 -c 標誌,shell 將執行這個命令。指針
mode: 只能是讀或者寫中的一種,獲得的返回值(標準 I/O 流)也具備和 type 相應的只讀或只寫類型。若是 type 是 「r」 則文件指針鏈接到 command 的標準輸出;若是 type 是 「w」 則文件指針鏈接到 command 的標準輸入。code
返回值:排序
若是調用成功,則返回一個讀或者打開文件的指針,若是失敗,返回NULL,具體錯誤要根據errno判斷進程
int pclose (FILE* stream)ip
參數說明:字符串
stream:popen返回的文件指針
返回值:
若是調用失敗,返回 -1
做用:
popen() 函數用於建立一個管道:其內部實現爲調用 fork 產生一個子進程,執行一個 shell 以運行命令來開啓一個進程這個進程必須由 pclose() 函數關閉。
例子:
管道讀:先建立一個文件test,而後再test文件內寫入「Read pipe successfully !」
#include 「stdio.h」
#include 「stdlib.h」
int main()
{
FILE *fp;
char buf[200] = {0};
if((fp = popen(「cat test」, 「r」)) == NULL) {
perror(「Fail to popen\n」);
exit(1);
}
while(fgets(buf, 200, fp) != NULL) {
printf(「%s」, buf);
}
pclose(fp);
return 0;
}
打印輸出: Read pipe successfully !
管道讀:
#include 「stdio.h」
#include 「stdlib.h」
int main()
{
FILE *fp;
char buf[200] = {0};
if((fp = popen(「cat > test1″, 「w」)) == NULL) {
perror(「Fail to popen\n」);
exit(1);
}
fwrite(「Read pipe successfully !」, 1, sizeof(「Read pipe successfully !」), fp);
pclose(fp);
return 0;
}
執行完畢後,當前目錄下多了一個test1文件,打開,裏面內容爲Read pipe successfully !
popen()和pclose()
若是你認爲上面建立和使用管道的方法過於繁瑣的話,你也可使用下面的簡單的方法:
庫函數:popen()和pclose();
原型:FILEpopen(charcommand,char*type);
返回值:若是成功,返回一個新的文件流。
若是沒法建立進程或者管道,返回NULL。
此標準的庫函數經過在系統內部調用pipe()來建立一個半雙工的管道,而後它建立一個子進程,啓動shell,最後在shell上執行command參數中的命令。管道中數據流的方向是由第二個參數type控制的。此參數能夠是r或者w,分別表明讀或寫。但不能同時爲讀和寫。在Linux系統下,管道將會以參數type中第一個字符表明的方式打開。因此,若是你在參數type中寫入rw,管道將會以讀的方式打開。 雖然此庫函數的用法很簡單,但也有一些不利的地方。例如它失去了使用系統調用pipe()時能夠有的對系統的控制。儘管這樣,由於能夠直接地使用shell命令,因此shell中的一些通配符和其餘的一些擴展符號均可以在command參數中使用。
使用popen()建立的管道必須使用pclose()關閉。其實,popen/pclose和標準文件輸入/輸出流中的fopen()/fclose()十分類似。
庫函數:pclose();
原型:intpclose(FILE*stream);
返回值:返回系統調用wait4()的狀態。
若是stream無效,或者系統調用wait4()失敗,則返回-1。
注意此庫函數等待管道進程運行結束,而後關閉文件流。庫函數pclose()在使用popen()建立的進程上執行wait4()函數。當它返回時,它將破壞管道和文件系統。 在下面的例子中,用sort命令打開了一個管道,而後對一個字符數組排序:
#include<stdio.h>
#defineMAXSTRS5
intmain(void)
{
intcntr;
FILE*pipe_fp;
char*strings[MAXSTRS]={"echo","bravo","alpha",
"charlie","delta"};
/Createonewaypipelinewithcalltopopen()/
if((pipe_fp=popen("sort","w"))==NULL)
{
perror("popen");
exit(1);
}
/Processingloop/
for(cntr=0;cntr<MAXSTRS;cntr++){
fputs(strings[cntr],pipe_fp);
fputc('\n',pipe_fp);
}
/Closethepipe/
pclose(pipe_fp);
return(0);
}
由於popen()使用shell執行命令,因此全部的shell擴展符和通配符均可以使用。此外,它還能夠和popen()一塊兒使用重定向和輸出管道函數。再看下面的例子:
popen("ls~scottb","r");
popen("sort>/tmp/foo","w");
popen("sort|uniq|more","w");
下面的程序是另外一個使用popen()的例子,它打開兩個管道(一個用於ls命令,另外一個用於
sort命令):
#include<stdio.h>
intmain(void)
{
FILE*pipein_fp,*pipeout_fp;
charreadbuf[80];
/Createonewaypipelinewithcalltopopen()/
if((pipein_fp=popen("ls","r"))==NULL)
{
perror("popen");
exit(1);
}
/Createonewaypipelinewithcalltopopen()/
if((pipeout_fp=popen("sort","w"))==NULL)
{
perror("popen");
exit(1);
}
/Processingloop/
while(fgets(readbuf,80,pipein_fp))
fputs(readbuf,pipeout_fp);
/Closethepipes/
pclose(pipein_fp);
pclose(pipeout_fp);
return(0);
}
最後,咱們再看一個使用popen()的例子。此程序用於建立一個命令和文件之間的管道:
#include<stdio.h>
intmain(intargc,char*argv[])
{
FILE*pipe_fp,*infile;
charreadbuf[80];
if(argc!=3){
fprintf(stderr,"USAGE:popen3[command][filename]\n");
exit(1);
}
/Open up input file/
if((infile=fopen(argv[2],"rt"))==NULL)
{
perror("fopen");
exit(1);
}
/Create one way pipe line with call topopen()/
if((pipe_fp=popen(argv[1],"w"))==NULL)
{
perror("popen");
exit(1);
}
/Processingloop/
do{
fgets(readbuf,80,infile);
if(feof(infile))break;
fputs(readbuf,pipe_fp);
}while(!feof(infile));
fclose(infile);
pclose(pipe_fp);
return(0);
}
下面是使用此程序的例子:
popen3sortpopen3.c
popen3catpopen3.c
popen3morepopen3.c
popen3catpopen3.c|grepmain