program tip

실용적인 예는 dup 또는 dup2를 사용합니다.

radiobox 2020. 11. 28. 08:58
반응형

실용적인 예는 dup 또는 dup2를 사용합니다.


나는 무엇을 dup/dup2 무엇을하는지 알고 있지만 그것이 언제 사용 될지 모른다.

실용적인 예가 있습니까?

감사.


한 가지 예로 I / O 리디렉션이 있습니다. 이를 위해 자식 프로세스를 포크하고 stdin 또는 stdout 파일 설명자 (0 및 1)를 닫은 다음 선택한 다른 파일 설명자에서 dup ()을 수행합니다. 그러면 현재 사용 가능한 가장 낮은 파일 설명자에 매핑됩니다. 케이스 0 또는 1

이것을 사용하면 이제 응용 프로그램을 인식하지 못하는 모든 자식 프로세스를 실행할 수 있으며 자식이 stdout에 쓸 때 (또는 구성한대로 stdin에서 읽을 때마다) 데이터가 제공된 filedescriptor에 대신 기록됩니다.

쉘은이를 사용하여 파이프로 명령을 구현합니다. 예를 들어 /bin/ls | more한 프로세스의 stdout을 다른 프로세스의 stdin에 연결합니다.


dup 및 dup2를 이해하는 가장 좋은 시나리오는 리디렉션입니다.
먼저 알아야 할 것은 시스템에 입력 및 출력을 처리하는 3 개의 기본 파일 ID (또는 출력 또는 입력 소스를 나타내는 변수)가 있다는 것입니다. 그들은이다 stdin, stdout, stderr, 그들이 정수에 0, 1, 2. fprintf또는 과 같은 대부분의 함수 coutstdout.
우리는 출력을 재 지정하려면, 하나의 방법은주고, 예를 들면, fprintf기능 이상의 인수가 나타내는 inout.
그러나 더 우아한 방법이 있습니다. 기본 파일 ID를 덮어 써서 출력을 받고자하는 파일을 가리 키도록 만들 수 있습니다. dup그리고 dup2바로이 상황에서 작동합니다.
이제 간단한 예제로 fprintf시작해 보겠습니다. 출력을 "chinaisbetter.txt"라는 txt 파일 로 리디렉션한다고 가정 해 보겠습니다 . 먼저이 파일을 열어야합니다.

int fw=open("chinaisbetter.txt", O_APPEND|O_WRONLY);

그런 다음 stdoutdup 함수를 사용하여 "chinaisbetter.txt"를 가리 킵니다.

dup2(fw,1);

이제 stdout (1)은 여전히 ​​1이지만 "chinaisbetter.txt"의 설명자를 가리 키지 만 출력은 이제 리디렉션됩니다.
그런 다음 printf정상적으로 사용할 수 있지만 결과는 화면에 직접 표시되지 않고 txt 파일에 표시됩니다.

printf("Are you kidding me? \n");

추신 :

  1. 이것은 직관적 인 설명 일 뿐이며 맨 페이지 나 자세한 정보를 확인해야 할 수도 있습니다. 실제로 여기에서 "복사"라고 말하지만 모든 것을 복사하는 것은 아닙니다.

  2. 여기서 파일 ID는 파일의 핸들러를 나타냅니다. 위에서 언급 한 파일 설명자는 레코드 파일의 정보를 구조화 한 것입니다.


POSIX 기능, 특히 자신을 복제하는 것처럼 보이는 기능에 대해 궁금 할 때 일반적으로 표준 자체확인하는 것이 좋습니다 . 하단에는 일반적으로 예제와 둘 다의 구현 (및 존재)에 대한 추론이 표시됩니다.

이 경우 :

다음 섹션은 정보를 제공합니다.

표준 출력을 파일로 리디렉션

다음 예제에서는 현재 프로세스에 대한 표준 출력을 pfd닫고에서 참조하는 파일로 이동하도록 표준 출력을 다시 할당 하고 정리를 위해 원래 파일 설명자를 닫습니다.

#include <unistd.h>
...
int pfd;
...
close(1);
dup(pfd);
close(pfd);
...

오류 메시지 리디렉션

다음 예제는 메시지를에서 stderr리디렉션합니다 stdout.

#include <unistd.h>
...
dup2(2, 1); // 2-stderr; 1-stdout
...

응용 프로그램 사용

없음.

이론적 해석

dup()dup2()기능이 중복됩니다. 그들의 서비스는 또한 fcntl()기능 에 의해 제공됩니다 . 많은 기존 응용 프로그램에서 사용하기 때문에 주로 역사적인 이유로이 IEEE Std 1003.1-2001 볼륨에 포함되었습니다.

표시된 간단한 코드 세그먼트는 동작면에서와 매우 유사하지만 dup2()IEEE Std 1003.1-2001의이 볼륨에 정의 된 다른 기능을 기반으로하는 준수 구현은 훨씬 더 복잡합니다. 가장 분명하지 않은 것은 단계 사이에서 호출 될 수있는 신호 포착 함수의 가능한 효과이며 파일 설명자를 할당하거나 할당 해제합니다. 이것은 신호를 차단함으로써 피할 수 있습니다.

dup2()함수는 .NET에서 형식이 안전하지 않은 버전으로 제공되는 형식 안전 버전의 기능을 제공하므로 노후화로 표시되지 않습니다 fcntl(). POSIX Ada 바인딩에 사용됩니다.

dup2()기능은 중요 영역에서 동기화 메커니즘으로 사용하기위한 것이 아닙니다.

[EBADF]의 설명에서 범위를 벗어난 경우는 유효하지 않은 경우로 처리됩니다. 관련되는 유일한 종류의 무효 성은 범위를 벗어 났는지 여부 이기 때문에 fildes및에 대한 설명 fildes2은 다릅니다 fildes2. fildes2, dup2()호출 시 열린 파일을 참조 하는지 여부 중요하지 않습니다 .

향후 방향

없음.

또한보십시오

close(), fcntl(), open(), IEEE 표준 1003.1-2001의 기본 정의 볼륨,<unistd.h>

변경 내역

1 호에 처음 출시되었습니다. SVID의 1 호에서 파생되었습니다.


한 가지 실용적인 예는 출력 메시지를 로그 파일과 같은 다른 스트림으로 리디렉션하는 것입니다. 다음은 I / O 리디렉션을위한 샘플 코드입니다. 여기
에서 원본 게시물을 참조 하십시오

#include <stdio.h>

main()
{
    int    fd;
    fpos_t pos;

    printf("stdout, ");

    fflush(stdout);
    fgetpos(stdout, &pos);
    fd = dup(fileno(stdout));
    freopen("stdout.out", "w", stdout);

    f();

    fflush(stdout);
    dup2(fd, fileno(stdout));
    close(fd);
    clearerr(stdout);
    fsetpos(stdout, &pos);        /* for C9X */

    printf("stdout again\n");
}

f()
{
printf("stdout in f()");
}

셸의 I / O 리디렉션은 dup2 / fcnlt 시스템 호출을 사용하여 구현 될 가능성이 높습니다.

$program 2>&1 > logfile.logdup2 함수를 사용하여 리디렉션 유형을 쉽게 에뮬레이션 할 수 있습니다 .

아래 프로그램은 stdout과 stderr을 모두 리디렉션합니다 $program 2>&1 > output. 즉, dup2 사용하는 동작을 에뮬레이트합니다 .

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

int
main(void){
    int close_this_fd;
    dup2(close_this_fd = open("output", O_WRONLY), 1);
    dup2(1,2);
    close(close_this_fd);
    fprintf(stdout, "standard output\n");
    fprintf(stderr, "standard error\n");
    fflush(stdout);
    sleep(100); //sleep to examine the filedes in /proc/pid/fd level.
    return;
}

vagrant@precise64:/vagrant/advC$ ./a.out
^Z
[2]+  Stopped                 ./a.out
vagrant@precise64:/vagrant/advC$ cat output
standard error
standard output
vagrant@precise64:/vagrant/advC$ ll /proc/2761/fd
total 0
dr-x------ 2 vagrant vagrant  0 Jun 20 22:07 ./
dr-xr-xr-x 8 vagrant vagrant  0 Jun 20 22:07 ../
lrwx------ 1 vagrant vagrant 64 Jun 20 22:07 0 -> /dev/pts/0
l-wx------ 1 vagrant vagrant 64 Jun 20 22:07 1 -> /vagrant/advC/output
l-wx------ 1 vagrant vagrant 64 Jun 20 22:07 2 -> /vagrant/advC/output

참고 URL : https://stackoverflow.com/questions/1720535/practical-examples-use-dup-or-dup2

반응형