
1
(stdout)/ 2
(stderr)을 시스템 호출에 전달했지만 read
여전히 잘 작동합니다. 그런 다음 0
(stdin)을 시스템 호출에 전달 write
하고 그것이 작동하는지 확인합니다!
int main(int argc, char** argv){
char buf[1024] = "abcdefghi\n";
write(0, buf, 10);
char readbuf[1024] = {0};
// read(1, readbuf, 10); works too
read(2, readbuf, 10);
write(2, readbuf, 10);
return 0;
}
산출:
abcdefghi
hey stdin <-- I input this
hey stdin
혼란스러워서 오류라고 생각했습니다.
실험:
그런 다음 fd 2를 리디렉션하려고 시도했습니다.
$ ./a.out 2>/dev/null
이번에는 읽기와 두 번째 쓰기가 모두 '표시'되지 않습니다. 출력은 다음과 같습니다
abcdefgi
그렇다면 stderr을 읽기에 사용할 수 있습니까?
그런 다음 stdout 및 stderr을 닫고 stdin의 복사본 두 개를 만듭니다.
int main(int argc, char** argv){
char buf[1024] = "abcdefghi\n";
close(1);
close(2);
dup2(0, 1);
dup2(0, 2);
write(0, buf, 10);
char redbuf[1024] = {0};
read(2, redbuf, 10);
write(2, redbuf, 10);
return 0;
}
다시 작동합니다.
산출:
abcdefghi
hey stdin <-- I input this
hey stdin
그렇다면 stdin을 쓰기에 사용할 수 있습니까?
여기에 설명이 필요합니다.
질문
나는 알고 싶다:
stdout/stderr을 읽기에 사용할 수 있는 이유는 무엇입니까?
왜 stdin을 쓰기에 사용할 수 있나요?
세 개의 스트림(표준 입력, 표준 출력, 표준 오류) 내부적으로하나개울 ?
그렇지 않다면 왜 이런 결과가 나오는 걸까요?
답변1
입력/출력/오류에 fd 0/1/2를 사용하는 것이 유일한 관례입니다. 리디렉션 없이 프로그램을 호출하면 세 가지 모두 tty를 참조하고 tty는 읽기 및 쓰기 액세스로 열립니다. 즉, 원하는 대로 읽거나 쓸 수 있습니다. 표현식 스트림은 FILE
C나 stream
C++와 같은 더 높은 수준의 I/O에 자주 사용되지만 동일한 스트림이라고 부를 수 있습니다.
이것이 리디렉션되거나 리디렉션되지 않은 예제 모두 입력한 텍스트를 에코하는 이유입니다.
반면에 리디렉션을 수행하면 셸은 읽기 전용 또는 쓰기 전용 액세스로 파일을 엽니다. 귀하의 예에서는 ./a.out 2>/dev/null
쓰기 대상이 0
리디렉션되지 않아 터미널에 계속 연결되어 화면에 표시됩니다. 읽기는 2
쓰기에만 연결되어 있으므로 /dev/null
실패해야 하지만 프로그램과의 차이점을 눈치채지 못할 것입니다. 에 쓰기가 2
성공했지만 에 기록되었습니다 /dev/null
. 잘못된 읽기 및 유효한 쓰기는 /dev/null
터미널에 표시되지 않습니다.
답변2
stdin/stdout/stderr를 리디렉션하지 않는 한 이러한 파일 설명자는 로그인 절차에 의해 열렸으며 tty
읽기 및 쓰기 관련 파일을 첫 번째 파일로 열고(결과적으로 파일 설명자 #0이 됨) 나중에 dup()
가져오기 위해 2번 호출합니다. stdout 및 stderr에 대한 파일 설명자.
에서 언급했듯이사용자로부터 명령을 읽을 수 있으면서 `less`는 어떻게 stdin에서 데이터를 가져오나요?이전에는(이전에는 /dev/tty
에 도입됨 UNIX
) 프로그램에서 확인을 요청할 때 more
읽었습니다 .stderr