[유닉스/리눅스] popen , pclose 정리 및 사용 예제

2021. 8. 1. 00:05W.IT/W.유닉스

  저는 popen과 pclose는 프로세스 사이에 입/출력 데이터를 어쩌면 가장 간단하게 읽고 쓰는 방법이라고 생각됩니다. 다만 pipe 함수보다 고수준이기에 읽고 쓰는 것에 대한 제약이 존재합니다.

popen

  popen 함수는 프로세스 내부에서 새로운 프로세스를 불러내어 명령어를 실행시키고 해당 프로세스와 입/출력 데이터를 주고 받을 수 있도록 FILE 포인터를 return 해주는 함수입니다.

 


 

 1. 함수 원형

 

#include <stdio.h>
FILE *popen(const char *command, const char *open_mode); 

 

  command

          → 입력되는 문자열은 실행시킬 명령에 대한 문자열로 매개 변수도 함께 넣어 실행할 수 있습니다.

 

  open_mode

          → 반드시 'r' (read) 'w' (write) 중 하나가 되어야 합니다.

 

                 'r'(read): 명령에 대한 표준 출력을 fread 함수를 통해 데이터를 읽을 수 있습니다.

                'w'(write): 명령에 대한 표준 입력을 fwrite 함수를 사용해 데이터를 쓸 수 있습니다.

                              다만, 결과는 확인할 수 없습니다.

                              키보드로 데이터를 입력해야 하는 명령어에 사용됩니다. 

 

  2. 함수 실행

   

   popen 함수의 실행은 먼저 sh(쉘)을 수행하여 인자로 "command" 파라미터로 들어온 문자열을 넘겨줌으로써 프로세스를 실행시킵니다.

 

          ※ 장점: 쉘 확장 가능

          ※ 단점: 쉘, 사용할 프로세스 두 개의 프로세스가 실행되며 리소스 소모가 큼

   

  3. 반환 값

 

    성공 시, FILE 포인터

    실패 시, NULL 포인터

 


pclose

  popen 함수를 사용하여 생성한 프로세스를 닫는 함수입니다.

 


 1. 함수 원형

 

#include <stdio.h>
int pclose(FILE *stream);

 

 2. 함수 실행

   

   파라미터로 들어온 FILE 포인터 스트림을 닫는다. 만약 아직 해당 프로세스가 완료되지 않은 상태라면 완료될때까지 기다립니다.

 

 3. 반환 값

 

   성공 시, -1 이외 값

   실패 시, -1 (errno 확인)

 


예제

 

 1. open_mode 'r' 

 

  sample_code.c (c file)

#include <stdio.h>
#include <string.h>
#include <errno.h>

int main(int ac, char *av[])
{
    FILE    *r_fp;
    char    buff[2048 + 1];
    int     rtn = 0;

    memset(buff, 0x00, sizeof(buff));
    r_fp = popen("pwd","r");
    if(!r_fp)
    {
        printf("popen ERROR (%d)\n", errno);
        return -1;
    }

    rtn = fread(buff, sizeof(char), sizeof(buff), r_fp);
    if(rtn > 0)
        printf("READ: %s\n", buff);

    pclose(r_fp);

    return 1;

}

  

 * 결과

won@Linux:~$ ./sample_code
READ: /home/won

 


 

 1. open_mode 'w' 

 

  sample_code1.c (c file)

#include <stdio.h>
#include <string.h>
#include <errno.h>

int main(int ac, char *av[])
{
    FILE    *w_fp;
    char    buff[2048 + 1];
    int     rtn = 0;

    w_fp = popen("./sample_code2","w");
    if(!w_fp)
    {
        printf("popen ERROR (%d)\n", errno);
        return -1;
    }

    memset(buff, 0x00, sizeof(buff));
    sprintf(buff, "Thank_you_for_reading!");

    fwrite(buff, sizeof(char), sizeof(buff), w_fp);

    pclose(w_fp);

    return 1;

}

 

 

 sample_code2.c (c file)

#include <stdio.h>
#include <string.h>

int main(int ac, char *av[])
{
    char buff[2048 + 1];

    memset(buff, 0x00, sizeof(buff));
    scanf("%s", buff);

    printf("INPUT: %s\n", buff);

    return 1;
}

 

 * 결과

won@Linux:~$ ./sample_code1
INPUT: Thank_you_for_reading!

 

 


 제 글에서 부족하거나 잘못된 부분이 있다면 댓글로 남겨주시길 부탁드립니다.

※ 제 글은 제가 코딩하면서 지속해서 확인하기 위한 히스토리 성 정보들이자 회사 생활 중 실제 프로그램을 코딩하며 중요하거나 필요했던 정보들을 공유하기 위해 적은 글입니다.