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 파일 설명자를 가져옵니다.
에서 언급했듯이사용자 명령을 읽을 수 있으면서도 표준 입력에서 데이터를 "덜" 얻을 수 있는 방법은 무엇입니까?과거에는 ( 이전에 /dev/tty
다루었습니다 UNIX
) more
확인을 요청할 때 읽은 것과 같은 프로그램이 있었습니다.stderr