리눅스 프로그래머를 위한 가이드
LIBRARY FUNCTION: popen();
PROTOTYPE: FILE *popen ( char *command, char *type);
RETURNS: 성공시 새로운 파일 스트림(stream)
fork(),pipe()호출이 실패했을 때 널(NULL)
NOTES: 명령어("command")를 사용하여 파이프를 만들고 fork/exec를 수행한다.
이 라이브러리 함수가 당신을 위해 까다로운 일을 수행하는 동안, 중요한 흥정(tradeoff)이 일어난다. pipe() 시스템 호출을 사용하고 fork/exec를 취급하는 것에 의해 당신은 잠시 통제권을 잃어버린다. 본 쉘이 직접 사용되므로, "command" 아규먼트 내에서 와일드 카드(wildcard)를 포함한 쉘 메타문자 확장(shell metacharacter expansion)이 가능하다.
popen()에 의해 만들어진 파이프는 pclose()로 닫아야만 한다. popen/pclose가 표준 파일 스트림 I/O 함수인 fopen(),fclose()와 매우 비슷하다는 것을 알았을 것이다.
LIBRARY FUNCTION: pclose();
PROTOTYPE: int pclose( FILE *stream );
RETURNS: wait4() 호출의 탈출 상태(exit status)
-1 스트림("stream")이 유효하지 않거나 wait4()가 실패했으면
NOTES: 파이프 프로세스가 종료되기를 기다렸다가 스트림을 닫는다.
sort명령어로 파이프를 열어 문자열의 배열을 정렬처리하는 예제를 살펴보자:
/*****************************************************************************
리눅스 프로그램머를 위한 가이드 - 6장 에서 발췌
(C)opyright 1994-1995, Scott Burkett
*****************************************************************************
MODULE: popen1.c
*****************************************************************************/
#include <stdio.h>
#define MAXSTRS 5
int main(void)
{
int cntr;
FILE *pipe_fp;
char *strings[MAXSTRS] = { "echo", "bravo", "alpha",
"charlie", "delta"};
/*popen() 호출을 사용하여 단방향 파이프를 만든다*/
if (( pipe_fp = popen("sort", "w")) == NULL)
{
perror("popen");
exit(1);
}
/*반복 처리*/
for(cntr=0; cntr<MAXSTRS; cntr++) {
fputs(strings[cntr], pipe_fp);
fputc('\n', pipe_fp);
}
/*파이프를 닫는다*/
pclose(pipe_fp);
return(0);
}
popen()는 자신의 명령을 수행하는데 쉘을 사용함으로, 모든 쉘 확장 문자들과 메타문자의 사용이
가능하다. 더군다나 redirection과 같은 보다 진보된 기술과 파이프의 출력조차 popen()에서
사용될 수 있다. 다음의 간단한 호출을 살펴보자:
popen("ls ~scottb", "r");
popen("sort > /tmp/foo", "w");
popen("sort | uniq | more", "w");
popen()의 또 다른 예인, 두개의 파이프(하나는 ls, 다른 하나는 sort)를 여는 작은 프로그램을
살펴보자:
/*****************************************************************************
리눅스 프로그램머를 위한 가이드 - 6장 에서 발췌
(C)opyright 1994-1995, Scott Burkett
*****************************************************************************
MODULE: popen2.c
*****************************************************************************/
#include <stdio.h>
int main(void)
{
FILE *pipein_fp, *pipeout_fp;
char readbuf[80];
/*popen() 호출을 사용하여 단방향 파이프를 만든다*/
if (( pipein_fp = popen("ls", "r")) == NULL)
{
perror("popen");
exit(1);
}
/*popen() 호출을 사용하여 단방향 파이프를 만든다*/
if (( pipeout_fp = popen("sort", "w")) == NULL)
{
perror("popen");
exit(1);
}
/*반복 처리*/
while(fgets(readbuf, 80, pipein_fp))
fputs(readbuf, pipeout_fp);
/*파이프를 닫는다*/
pclose(pipein_fp);
pclose(pipeout_fp);
return(0);
}
popen()의 마지막 예제를 위해, 넘겨받은 명령어와 파일명간의 파이프라인을 여는
일반적인 프로그램을 작성해 보자:
/*****************************************************************************
리눅스 프로그래머를 위한 가이드 - 6장 에서 발췌
(C)opyright 1994-1995, Scott Burkett
*****************************************************************************
MODULE: popen3.c
*****************************************************************************/
#include <stdio.h>
int main(int argc, char *argv[])
{
FILE *pipe_fp, *infile;
char readbuf[80];
if( argc != 3) {
fprintf(stderr, "USAGE: popen3 [command] [filename]\n");
exit(1);
}
/*입력 파일을 연다*/
if (( infile = fopen(argv[2], "rt")) == NULL)
{
perror("fopen");
exit(1);
}
/*popen() 호출을 사용하여 단방향 파이프를 만든다*/
if (( pipe_fp = popen(argv[1], "w")) == NULL)
{
perror("popen");
exit(1);
}
/*반복 처리*/
do {
fgets(readbuf, 80, infile);
if(feof(infile)) break;
fputs(readbuf, pipe_fp);
} while(!feof(infile));
fclose(infile);
pclose(pipe_fp);
return(0);
}
다음의 예를 가지고 이 프로그램을 수행시켜보자:
popen3 sort popen3.c
popen3 cat popen3.c
popen3 more popen3.c
popen3 cat popen3.c | grep main
Copyright (c) 1996,1997 by Euibeom.Hwang & SangEun.Oh All Rights Reserved
Email To:Webmaster ,
Another address
LAST UPDATE Nov 18,1997
Created Nov 15,1997