표준 스트림(standard streams)은 유닉스 및 유닉스 계열 운영 체제(일부는 윈도우에도 해당)에서 컴퓨터 프로그램과 그 실행 환경(일반적으로 단말기) 사이에 미리 연결된 입출력 통로를 가리킨다. 유닉스 이전의 대부분의 운영 체제에서는 프로그램이 사용할 입력 장치와 출력 장치를 명시적으로 연결해야 했으나, 유닉스는 데이터 스트림이라는 개념으로 장치를 추상화하여 프로그램이 어떤 장치와 연결되는지 알 필요 없이 데이터를 주고받을 수 있도록 하였다.
유닉스에서 동작하는 프로그램은 실행 시 세 개의 스트림이 자동으로 열리며, 이를 표준 스트림이라 부른다.
세 가지 표준 스트림
| 명칭 | 약어 | 파일 디스크립터 | C 언어 (stdio.h) | C++ |
|---|---|---|---|---|
| 표준 입력 | stdin | 0 | FILE* stdin; |
std::cin |
| 표준 출력 | stdout | 1 | FILE* stdout; |
std::cout |
| 표준 오류 | stderr | 2 | FILE* stderr; |
std::cerr, std::clog |
표준 입력 (Standard Input, stdin)
프로그램으로 들어가는 데이터(보통 문자열) 스트림이다. 프로그램은 read 명령을 이용하여 데이터 전송을 요청한다. 모든 프로그램이 입력을 요구하는 것은 아니며, 별도의 리다이렉션 없이 프로그램을 시작한 경우 표준 입력 스트림은 키보드로부터 데이터를 받는다.
표준 출력 (Standard Output, stdout)
프로그램이 출력 데이터를 기록하는 스트림이다. 프로그램은 write 명령을 이용하여 데이터 전송을 요청한다. 리다이렉션 없이 표준 출력은 프로그램을 시작한 텍스트 터미널(모니터)이 된다. 명령 수행이 성공적이어도 아무 메시지도 출력하지 않는 프로그램(예: mv, ren)도 존재한다.
표준 오류 (Standard Error, stderr)
프로그램이 오류 메시지나 진단 정보를 출력하기 위해 사용하는 또 다른 출력 스트림이다. 표준 출력과는 독립적인 스트림이며 별도로 리다이렉트될 수 있다. C++ 표준 헤더는 이 스트림에 대해 버퍼링되지 않는 std::cerr과 버퍼링을 이용하는 std::clog 두 변수를 제공한다.
동작 원리
터미널에 로그인 셸이 먼저 기동되고(사용자 인증이 끝나면) 대화형 셸이 기동된다. 이때 자동으로 터미널에 부착된 세 개의 표준 스트림이 상속된다. 이후 셸에서 실행되는(exec) 모든 명령들은 셸을 부모 프로세스로 삼아 세 개의 표준 스트림을 다시 상속받는다. 또한 파이프(|)나 리다이렉션(>, <, >>, 2> 등)를 통해 표준 스트림의 방향을 전환할 수 있다.
응용
표준 스트림은 일반적으로 텍스트(Latin-1 또는 UTF-8 인코딩)를 주고받는 대화식 사용에 많이 활용되지만, 이진 데이터를 전송하는 데에도 쓰일 수 있다. 프로그램 간에 표준 스트림을 연쇄적으로 연결(pipeline)하여, 한 프로그램의 출력을 다른 프로그램의 입력으로 사용할 수 있다. 대표적인 예로 pager나 more 유틸리티가 있다.
역사적 배경
유닉스의 획기적인 발전 중 하나는 장치의 추상화였다. 유닉스 이전의 운영 체제에서는 펀치 카드 리더기, 자기 테이프 드라이브, 라인 프린터 등 각 장치에 대해 환경 설정을 제어하거나 파일 테이블에 접근하는 등 복잡한 작업이 필요했다. 유닉스는 이러한 복잡성을 순차적인 데이터 바이트 흐름(데이터 스트림)이라는 개념으로 해소하였고, 표준 스트림이 지원된 이후 유닉스 C 실행 환경 및 대부분의 C 실행 환경(이후의 C 파생 언어 포함)에서 운영 체제와 상관없이 동일한 기능을 제공하게 되었다.