명령어의 실행 결과를 화면에 표시되는 것을 파일로 저장하기 위해서 파일 redirect를 이용한다. 

예를 들면 ls -al > ls.txt 라고 하면 ls -al 한 결과가 화면에 표시되지 않고 ls.txt 파일에 저장된다.
또한 ls -al >> ls.txt는 ls.txt 파일이 기존에 존재하는 파일이면 ls -al 의 결과가 파일에 추가된다. 이와 같은 처리를 프로그램 내에서 구현할 수는 있을까? 이를 가능하게 해주는 함수가 바로 dup2(2)함수이다.

 

    dup2(2)함수는 열려진 file descriptor를 다른 file descriptor로 복사한다. 이를 통하여 파일의 입출력의 방향을 변경할 수 있다. 일반적으로 알려진 file descriptor로는 표준 입력(0), 표준 출력(1), 표준 오류(2)가 있다. 이들 표준 입출력 descriptor에 file명으로 open한 file descriptor를 dup2(2)로 복사를 하면 표준 입출력은 더 이상 기존의 화면 입출력이 아닌 파일 입출력으로 바뀌게 된다.

 


함수 사용법

 

dup2(2) : duplicate 2 - 함수 사용법

#include <unistd.h>

int dup2(int oldfd, int newfd);

설명
    dup2는 newfd 파일 descripter가 이미 open된 파일이면 close하고 oldfd를 newfd로 복사를 합니다.
    이때, newfd와 oldfd는 file descripter 번호는 다르지만 똑같이 행동합니다. 
    그러지만 두 file descriptor는 다른 descriptor이므로 하나를 close한다고 해서 함께 close되지 않는다. 

parameter
    oldfd : 복사하려는 원본 file descripter
    newfd : 복사되는 target file descripter 
            (만약 newfd가 열려진 file descripter이면, 먼저 close후에 복사함)

return 
   정상인 경우: -1 이외의 값
   오류인 경우: -1 , 오류 상세 내용은 errno 전역변수에 저장됨

 

 


활용 예제

 

Example). init_log_file( )  
init_log_file( )함수는 이 함수를 호출한 후부터 prinft( ... )나 fprintf(stderr, ...)로 출력한 모든 화면 출력을 log_file로 넘겨진 파일명의 파일로 출력된다.

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int init_log_file(const char *log_file)
{
    int fd;

    /* | O_APPEND 가 붙으면 기존에 파일이 존재하면 파일에 추가한다. */
    if((fd = open(log_file, O_WRONLY | O_CREATE | O_APPEND)) == -1)
    {
        return 0;
    }

    /* 표준 출력을 program.log 파일로 redirection 함 */
    dup2(fd, 1); 

    /* 표준 오류를 program.log 파일로 redirection 함 */
    dup2(fd, 2);

    close(fd);
    return 1;
}

 


Example) init_log_file 함수 사용

#include <stdio.h>
#include <string.h>
....
#define LOG_FILE_NAME   "program.log"

int main(int argc, char **argv)
{
    // 변수 선언
    ......
    
    /* 
        프로그램 실행시에 첫번째 파라미터가 -DEBUG이면 화면으로 출력하고
        그렇지 않으면 "programe.log" 파일로 출력한다.
    */
    if(argc > 2 && strcmp(argv[1], "-DEBUG") != 0) {
        init_log_file(LOG_FILE_NAME);
    }
    
    ......
    
    /* 업무 로직 ...... */
    
    printf("[D] %.20s - %.30s() [%5d] : 데이터를 초기화 합니다.\n", __FILE__, __func__, __LINE__);
    
    ......
    
    fprintf(stderr, "[E] %.20s - %.30s() [%5d] : xxxx 오류 입니다.\n", __FILE__, __func__, __LINE__);
    
    ......
    
    return 0;
}

위와 같이 로그를 출력하는 프로그램을 만들기 귀찮은 경우에 테스트 시에는 화면으로 표시하고 실제 사용에는 파일로 출력하는 예제입니다. 이  init_log_file( ) 함수가 호출이 된 이후부터는 화면 출력이 모두 program.log 파일로 저장되게 된다. 또한 이후에 fork( )를 통해서 새로 생성한 child process의 모든 표준 출력과 표준 오류도 program.log에 저장된다.
 

블로그 이미지

사용자 자연&사람

행복한 개발자 programmer since 1995.

Tag , , ,

댓글을 달아 주세요