2012-10-31 1 views
1

(내 돌보는하지 않는 사과는 최근 받아 - 나는 약간의 시간을 얻을 정도로 빨리 할 것입니다, 그냥이 발생한 것을 지금이 질문을하고 싶었)Linux C : 사용하지 않는 파일 설명자는 어떻게됩니까?

을 다음 C 프로그램을 고려 :

int main(void) { 
    write(3, "aaaaaa\n", 7); 
    write(2, "bbbbbb\n", 7); 
    write(1, "cccccc\n", 7); 
    return 0; 
} 

내가 구축하고이 같은 bash 쉘에서 실행 :

$ gcc -o wtest wtest.c 
$ ./wtest 3>/dev/stdout 
aaaaaa 
bbbbbb 
cccccc 

내가 인해 stdout에 FD 3의 쉘 리디렉션으로,이 경우에, 그것을 볼 수있는 방법은, 그 파일 기술자는 이제 "사용"입니다 (안 적어도 C 코드에는 파일 열기가 없으므로 "열림"에 대해 확신합니다.) 따라서 우리는 cccccc 문자열 출력을 예상대로 터미널에 전달합니다. 내가 리디렉션을 사용하지 않는 경우

는, 출력은 이것이다 :

$ ./wtest 
aaaaaa 
bbbbbb 

이제 3 리디렉션되지 전략 중 - 예상대로 그렇게 cccccc 문자열을 다시 출력되지 않습니다.

 

내 질문은 - 어떻게 그 cccccc 바이트 일어 났는가? 마치 fd 3을 /dev/null으로 리다이렉 한 것처럼 그들은 같은 의미로 사라졌습니까? 대 "3>/dev/null"를 재전송 사이의 성능 차이가있을 것이다 : 특정 경우에 I가 "닫기"는 FD (3) 출력하려는 ​​것으로 가정 또한

, (

$ ./wtest 3>/dev/null 

같이) fd 3이 정말로 긴 바이트 스트림을 출력한다면, "3>/dev/null"경우에 기록 된 바이트 당 명령어 페널티가 존재할 것인데, 그렇지 않다면 스트리밍 데이터의 관점에서 보면 쉘에서 fd 3을 다루지 않는다. fd 주소 3)? 모든 답변에 미리

 

많은 감사,
건배!

+0

한 번에 한 가지 질문 만하십시오.이 포럼이 아니라 Q/A 사이트입니다. –

+0

인용 된 프로그램이 인용 된 결과와 일치하지 않기 때문에 약간 혼란 스럽습니다. "cccccc"는 fd 3에 기록되지 않지만 fd 1에 기록됩니까? –

답변

4

제 질문은 - 해당 cccccc 바이트는 어떻게 되었습니까?

아무 것도 없습니다. write의 리턴 코드를 캡처하지 못했을 때 오류가 있음을 알려주고 이 무엇인지 알려주는 메시지가 표시되어야합니다. "영구적 인"항목에 대한 의문점이있는 것처럼 보입니다. 컴파일러가 처음부터 쓴 문자열 리터럴에 여전히 앉아있다. write은 바이트를 스트림에 복사합니다.

0

옌스입니다. strace 하에서 두 가지 상황 모두에서 프로그램을 실행하면 리디렉션 할 때 write가 작동 함을 알 수 있습니다. 쉘이 실행 파일을 fork하기 전에 pipe()를 호출했기 때문입니다.

당신이 리디렉션없이 strace를 보면 : 가장 좋은 방법을 생각 나게

write(3, "aaaaaa\n", 7)     = -1 EBADF (Bad file descriptor) 
write(2, "bbbbbb\n", 7bbbbbb)     = 7 
write(1, "cccccc\n", 7cccccc)     = 7 

- 항상 반환 값을 확인합니다.

+0

파일로의 리다이렉션은'pipe'가 아니라'open'으로 처리됩니다. –

+0

쉘의 경우 pipe가 아니고 두 개의 디스크립터를 얻은 다음 dup2 (3, new_in_fd)를 열고 dest 파일, dup2 (new_out_fd, dest fd)를 엽니 다. – izar

+1

명령에'| '가 없으면 파이프가 열리지 않습니다. 셸은 파일을 열거 나, fork, dups를 자식에 넣고 필요한 프로그램을 실행합니다. fd를'fstat'와'S_ISFIFO'를 가진 파이프인지 테스트하는 C 프로그램에 fd를 넘김으로써 이것을 검증 할 수 있습니다. –

관련 문제