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