실용적인 예는 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
또는 과 같은 대부분의 함수 cout
는 stdout
.
우리는 출력을 재 지정하려면, 하나의 방법은주고, 예를 들면, fprintf
기능 이상의 인수가 나타내는 in
및 out
.
그러나 더 우아한 방법이 있습니다. 기본 파일 ID를 덮어 써서 출력을 받고자하는 파일을 가리 키도록 만들 수 있습니다. dup
그리고 dup2
바로이 상황에서 작동합니다.
이제 간단한 예제로 fprintf
시작해 보겠습니다. 출력을 "chinaisbetter.txt"라는 txt 파일 로 리디렉션한다고 가정 해 보겠습니다 . 먼저이 파일을 열어야합니다.
int fw=open("chinaisbetter.txt", O_APPEND|O_WRONLY);
그런 다음 stdout
dup 함수를 사용하여 "chinaisbetter.txt"를 가리 킵니다.
dup2(fw,1);
이제 stdout (1)은 여전히 1이지만 "chinaisbetter.txt"의 설명자를 가리 키지 만 출력은 이제 리디렉션됩니다.
그런 다음 printf
정상적으로 사용할 수 있지만 결과는 화면에 직접 표시되지 않고 txt 파일에 표시됩니다.
printf("Are you kidding me? \n");
추신 :
이것은 직관적 인 설명 일 뿐이며 맨 페이지 나 자세한 정보를 확인해야 할 수도 있습니다. 실제로 여기에서 "복사"라고 말하지만 모든 것을 복사하는 것은 아닙니다.
여기서 파일 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.log
dup2 함수를 사용하여 리디렉션 유형을 쉽게 에뮬레이션 할 수 있습니다 .
아래 프로그램은 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
'program tip' 카테고리의 다른 글
식 트리 람다는 null 전파 연산자를 포함 할 수 없습니다. (0) | 2020.11.28 |
---|---|
SVN / TortoiseSVN 고통스럽게 느림 (0) | 2020.11.28 |
Lucene / Solr과 같은 문서 저장소가 NoSQL 대화에 포함되지 않는 이유는 무엇입니까? (0) | 2020.11.28 |
Visual Studio 2010 기본 확대 / 축소 수준 (0) | 2020.11.28 |
VB.NET null 병합 연산자? (0) | 2020.11.28 |