stdin, stdout 및 stderr에 대해 혼란 스럽습니까?


230

나는이 세 파일의 목적과 다소 혼동됩니다. 내 이해가 정확 stdin하면 프로그램이 프로세스에서 작업을 실행하기 위해 요청에 쓰는 stdout파일, 커널이 출력을 쓰는 stderr파일 및 정보를 요청하는 프로세스 가 파일에 들어있는 파일입니까? 모든 예외가 입력됩니다. 이러한 파일이 실제로 발생하는지 확인하기 위해 이러한 파일을 열면 제안한 것이 아무것도 없습니다!

내가 알고 싶은 것은이 파일의 목적이 정확히 무엇인지, 기술 전문 용어로 대답을 완전히 바보로 만들었습니다!


36
관찰 :이 질문은 2010 년에 받아 들여졌지만 요즘에는 매우 빠르게 하향 투표 될 것입니다.
byxor

3
@Brandon 이유를 제시 할 수 있습니까? 귀하의 의견에 도움이 될 것이라고 생각합니다.
독립

3
@byxor 공정하게, 나는 묻습니다 : op의 게시물은 사람들에게 그의 코드를 디버깅하도록 도와달라고 요청 했습니까? Shouvik은 stdin, stdout 및 stderr의 목적과 관련하여 질문을 한 것 같습니다. op의 게시물이 호기심에서 벗어난 것 같습니다. (실제로이 글을 배우고 있습니다.이 게시물을 삭제하지 않은 것에 대해 감사합니다.)
sansae

2
@ user123456이 맞습니다. 저는 소프트웨어 개발자가되는 것을 배우고 있었고 S / O는 프로그래밍에 대해 배우기 좋은 곳이었습니다. 우리는 원래 컴퓨팅 과학에 관한 모든 질문에 대해 일종의 위키 서비스로 만들었습니다. #juniorDevForLife
Shouvik

3
@Shouvik은 역사에 대해 감사드립니다. 소프트웨어 개발자가되는 법을 배우고 있습니다 (sf의 멋진 캠프에 수용되었습니다). 나는 여전히 S / O를 처음 접했고 게시 할 수있는 것과 게시 할 수없는 것이 확실하지 않습니다. 여기서 검토는 매우 엄격 할 수 있습니다. 해시 태그가 마음에 듭니다. #juniorDevForLife. 토론에 아무것도 추가하지 않기 때문에 여기에 의견을 쓰지 않고 오후에 pm을하지만 S / O에 pm 시스템이 있다고 생각하지 않습니다. 좋은 하루 보내세요
sansae

답변:


251

표준 입력 - 정보를 얻기 위해 프로세스가 읽는 파일 핸들 입니다.

표준 출력 -프로세스는이 파일 핸들에 일반 정보를 씁니다.

표준 오류 -프로세스가이 파일 핸들에 오류 정보를 씁니다.

그것은 내가 할 수있는 것처럼 바보처럼 보입니다 :-)

물론 그것은 대부분 관습에 따른 것입니다. 원하는 경우 오류 정보를 표준 출력에 쓰는 것을 막을 수있는 것은 없습니다. 세 개의 파일 핸들을 완전히 닫고 I / O를 위해 자신의 파일을 열 수도 있습니다.

프로세스가 시작되면 이러한 핸들이 이미 열려 있어야하며 핸들에서 읽고 쓸 수 있습니다.

기본적으로 터미널 장치 (예 :)에 연결되어 /dev/tty있지만 프로세스를 시작하기 전에 이러한 핸들과 특정 파일 및 / 또는 장치 (또는 다른 프로세스의 파이프 라인) 사이의 연결을 설정할 수 있습니다 (일부 가능한 조작은 다소 영리합니다.)

예를 들면 다음과 같습니다.

my_prog <inputfile 2>errorfile | grep XYZ

어느 것이 :

  • 에 대한 프로세스를 만듭니다 my_prog.
  • inputfile표준 입력으로 엽니 다 (파일 핸들 0).
  • errorfile표준 오류로 엽니 다 (파일 핸들 2).
  • 에 대한 다른 프로세스를 만듭니다 grep.
  • 의 표준 출력 my_prog을의 표준 입력에 연결하십시오 grep.

당신의 의견을 다시 :

/ dev 폴더에서 이러한 파일을 열면 실행중인 프로세스의 출력을 어떻게 볼 수 없습니까?

정상적인 파일이 아니기 때문입니다. UNIX는 모든 것을 파일 시스템의 파일로 어딘가에 제공하지만 가장 낮은 레벨에서는 그렇지 않습니다. /dev계층 구조의 대부분의 파일은 문자 또는 블록 장치이며 사실상 장치 드라이버입니다. 크기는 없지만 주 장치 번호와 부 장치 번호가 있습니다.

파일을 열면 실제 파일이 아닌 장치 드라이버에 연결되며 장치 드라이버는 별도의 프로세스를 개별적으로 처리해야한다는 것을 알기에 충분히 똑똑합니다.

Linux /proc파일 시스템 에서도 마찬가지입니다 . 그것들은 실제 파일이 아니며 커널 정보로 엄격하게 제어되는 게이트웨이입니다.


1
귀하의 답변입니다. 나는 당신이 묘사 한 것에서 파일의 목적을 이해할 수 있지만, 한 단계 더 나아가고 싶습니다. / dev 폴더에서 이러한 파일을 열면 실행중인 프로세스의 출력을 볼 수 없습니다. 터미널에서 top을 실행한다고 가정하면 stdout 파일에 결과를 주기적으로 출력하지 않아야하므로 업데이트 될 때이 파일에 출력되는 인스턴스를 볼 수 있어야합니다. 그러나 이것은 그렇지 않습니다.이 파일들도 동일하지 않습니다 (/ dev 디렉토리에있는 파일들).
Shouvik

7
그것들은 기술적으로 파일이 아니기 때문입니다. 이들은 특정 장치에 쓸 장치를 나타내는 장치 노드입니다. 유닉스는 모든 것을 파일 추상화로 보여줄 수 있지만 가장 심층적 인 수준으로 만들지는 않습니다.
paxdiablo

1
쉘 재 지정 기능을 사용하십시오. xyz >xyz.out다른 프로세스에서 읽을 수있는 실제 파일에 표준 출력을 씁니다. xyz | grep something연결할 xyz에 표준 출력을 grep보다 직접적으로 stdin을. 그런 식으로 제어하지 않는 프로세스에 자유롭게 액세스하려면 원하는 방식으로 /proc커널에 연결하여 출력을 필터링하는 코드를 작성하거나 코드를 작성 해야합니다 . 이 다른 솔루션 수 있지만, 그들은 모두 아마 서로 내적인 위험과 같은 것 할 수있다
paxdiablo

20
@Shouvik, 이것은 현재 실행중인 프로그램이 처음 연 파일 설명자에 대한 /dev/stdin심볼릭 링크 /proc/self/fd/0입니다. 따라서 항상 '현재 실행중인 프로그램'을 가리 키기 /dev/stdin때문에 지적하는 것은 프로그램마다 변경됩니다 /proc/self/. (프로그램이 open전화를 거는 동안) /dev/stdin친구는 setuid 셸 스크립트를보다 안전하게 만들고 /dev/stdin파일에서만 작동하는 프로그램에 파일 이름 을 전달할 수 있지만 대화식으로 더 제어하려는 경우가 있습니다. (언젠가 이것은 당신이 알아야 할 유용한 트릭입니다. :)
sarnold

1
@ CarlosW.Mercado, 파일 은 데이터의 물리적 표현입니다. 예를 들어, 비트는 하드 디스크에 저장됩니다. 파일 핸들 은 일단 파일을 열면 해당 파일을 참조하는 데 사용되는 작은 토큰입니다.
paxdiablo

62

그런 말을하는 것이 더 정확한 것 stdin, stdout그리고 stderr오히려 파일보다 "I / O는 스트림"입니다. 알다시피, 이러한 엔티티는 파일 시스템에 존재하지 않습니다. 그러나 I / O에 관한 한 유닉스의 철학은 "모든 것이 파일"입니다. 실제로, 같은 라이브러리 함수와 인터페이스를 (사용할 수있는 정말 수단 printf, scanf, read, write, select는 I / O 스트림은 키보드, 디스크 파일, 소켓, 파이프에 연결되어 있는지 여부에 대한 걱정없이, 등) 또는 다른 I / O 추상화.

대부분의 프로그램은 이렇게 입력, 쓰기 출력 및 로그 오류, 읽을 필요 stdin, stdoutstderr프로그래밍 편의를 위해, 당신을 위해 미리 정의되어 있습니다. 이것은 규칙 일 뿐이며 운영 체제에 의해 시행되지 않습니다.


입력 해 주셔서 감사합니다. 프로세스의 출력 데이터 스트림을 가로 채서 내 파일로 출력하는 방법을 알고 있습니까?
Shouvik

51

위의 답변을 보완하기 위해 다음은 리디렉션에 대한 요약입니다. 리디렉션 치트 시트

편집 :이 그래픽은 완전히 정확하지 않지만 왜 그런지 잘 모르겠습니다 ...

그래픽은 2> & 1은 &>와 동일한 효과를 나타냅니다.

ls Documents ABC > dirlist 2>&1
#does not give the same output as 
ls Documents ABC > dirlist &>

4
당신의 의견은 받아 들여진 대답과 결합하여 완벽하게 이해되고 명확하게 설명합니다! 감사!
Mykola 2016 년

1
그림은 천 단어의 가치가 있습니다!
tauseef_CuriousGuy

22

이해가 완전히 뒤 떨어질 까봐 걱정됩니다. :)

커널의 관점이 아니라 프로그램의 관점 에서 "표준 입력", "표준 출력"및 "표준 오류"를 생각하십시오 .

프로그램이 출력을 인쇄해야 할 경우 일반적으로 "표준 출력"으로 인쇄합니다. 프로그램은 일반적으로 표준 출력으로 만 출력하고 표준 출력으로 printf만 출력합니다.

프로그램이 오류 정보를 인쇄해야하는 경우 (예외는 아니지만 훨씬 높은 수준으로 부과되는 프로그래밍 언어 구성) 일반적으로 "표준 오류"로 인쇄됩니다. 일반적 fprintf으로을 사용하여 인쇄 할 때 사용할 파일 스트림을 허용합니다. 표준 출력, 표준 오류, 또는 연 상태 다른 파일 : 파일 스트림은 쓰기 위해 열려있는 파일 수 fopen또는 fdopen.

"표준 입력"은 파일이 입력을 읽 fread거나 fgets, 또는 , 또는를 사용하여 읽을 때 사용됩니다 getchar.

이러한 파일은 다음 과 같이 셸에서 쉽게 리디렉션 할 수 있습니다 .

cat /etc/passwd > /tmp/out     # redirect cat's standard out to /tmp/foo
cat /nonexistant 2> /tmp/err   # redirect cat's standard error to /tmp/error
cat < /etc/passwd              # redirect cat's standard input to /etc/passwd

또는 전체 엔칠 라다 :

cat < /etc/passwd > /tmp/out 2> /tmp/err

두 가지 중요한 경고가 있습니다. 첫째, "표준 입력", "표준 출력"및 "표준 오류"는 단지 규칙입니다. 그것들은 매우 강력한 규칙이지만, 다음 grep echo /etc/services | awk '{print $2;}' | sort과 같은 프로그램을 실행할 수 있다는 것은 매우 합의입니다. 각 프로그램의 표준 출력을 파이프 라인에서 다음 프로그램의 표준 입력에 연결하십시오.

둘째, 내가 파일 스트림 (작업을위한 표준 ISO C의 기능을 준 FILE *객체) - 커널 레벨에서, 모든 파일 기술자 (인 int파일 테이블에 대한 참조) 및 훨씬 낮은 수준의 같은 작업 readwrite하지 않습니다, ISO C 기능을 적절히 버퍼링하십시오. 나는 그것을 간단하게 유지하고 더 쉬운 기능을 사용하려고 생각했지만 대안을 알아야한다고 생각했습니다. :)


프로세스가 실행될 때이 stderr 파일에 오류를 기록하거나 프로그램이 소스에서 컴파일 될 때도 마찬가지입니다. 또한 컴파일러의 관점에서 이러한 파일에 대해 이야기 할 때 프로그램과 비교할 때와 다른가요?
Shouvik

1
@Shouvik, 컴파일러는 자체 stdin, stdout 및 stderr를 가진 또 다른 프로그램입니다. 컴파일러가 경고 또는 오류를 작성해야 할 경우 stderr에 작성합니다. 컴파일러 프런트 엔드가 어셈블러에 대한 중간 코드를 출력 할 때 stdout에 중간 코드를 작성하고 stdin에서 해당 입력을 받아 들일 수 있지만 사용자의 관점에서 보면 모든 것이 비현실적 일 수 있습니다.) 컴파일 된 프로그램, 해당 프로그램은 표준 오류에 오류를 쓸 수 있지만 컴파일되는 것과는 아무런 관련이 없습니다.
sarnold

그 정보 토큰에 감사드립니다. 어쨌든 그 관점에서 그것을 보지 못하는 것은 꽤 바보 같은 것 같습니다 ... : P
Shouvik

1
표준은 프로그램을 인쇄하는 데 도움이된다고 말하는 것입니다
babygame0ver

9

stdin

콘솔을 통한 입력을 읽습니다 (예 : 키보드 입력). scanf와 함께 C에서 사용

scanf(<formatstring>,<pointer to storage> ...);

표준

콘솔에 출력을 생성합니다. printf와 함께 C에서 사용

printf(<string>, <values to print> ...);

stderr

콘솔에 '오류'출력을 생성합니다. fprintf와 함께 C에서 사용

fprintf(stderr, <string>, <values to print> ...);

리디렉션

stdin의 소스를 리디렉션 할 수 있습니다. 예를 들어, 키보드 입력에서 오는 대신 파일 ( echo < file.txt) 또는 다른 프로그램 ( ps | grep <userid>) 에서 올 수 있습니다 .

stdout, stderr의 대상을 리디렉션 할 수도 있습니다. 예를 들어 stdout은 파일로 리디렉션 될 수 있습니다. ls . > ls-output.txt이 경우 출력이 파일에 기록됩니다 ls-output.txt. STDERR 리디렉션 할 수 있습니다2>.


8

사람들 stderr이 오류 메시지에만 사용해야한다고 말하는 것은 오해의 소지가 있다고 생각합니다.

또한 데이터의 잠재적 다운 스트림 소비자가 아닌 명령을 실행하는 사용자를위한 정보 메시지에도 사용해야합니다 (예 : 여러 명령을 연결하는 쉘 파이프를 실행하는 경우 "항목 30 가져 오기"와 같은 정보 메시지를 원하지 않음) stdout소비자를 혼동하기 때문에 42424 "로 표시 되지만 여전히 사용자가 볼 수 있습니다.

참조 역사적 근거에 대해 :

"모든 프로그램은 표준 출력에 진단을 배치했습니다. 이로 인해 출력이 파일로 경로 재 지정 될 때 항상 문제가 발생했지만 출력이 의심되지 않는 프로세스로 전송 될 때 견딜 수 없게되었습니다. 그럼에도 불구하고 표준 입력의 단순성을 위반하지 않습니다. 표준 출력 모델을 사용하는 사람들은 v6을 통해이 상황을 견뎌냈지만 곧 데니스 리치 (Dennis Ritchie)는 표준 오류 파일을 도입하여 고르 디안 매듭을 끊었습니다. 자신을 식별합니다. "


3

ps -aux를 사용하면 cat / proc / (pid) / fd / 0을 호출하여 / proc /에 / proc / (pid) /로 나열되는 현재 프로세스가 표시됩니다. 표준 프로세스에서 찾은 모든 것을 인쇄합니다. 그 과정을 생각합니다. 아마

/ proc / (pid) / fd / 0-표준 출력 파일
/ proc / (pid) / fd / 1-표준 입력 파일
/ proc / (pid) / fd / 2-표준 오류 파일

예를 들어내 터미널 창

그러나 다른 프로세스는 일반적으로 0에 아무것도 없었지만 많은 사람들이 2로 작성된 오류를 가지고 있습니다.


3

이 파일들에 대한 권위있는 정보는 man 페이지를 확인하고 터미널에서 명령을 실행하십시오.

$ man stdout 

그러나 간단한 대답을 위해 각 파일은 다음과 같습니다.

스트림 아웃을위한 stdout

스트림 입력을위한 stdin

오류 또는 로그 메시지 인쇄를위한 stderr .

각 유닉스 프로그램은 각각의 스트림을 가지고 있습니다.


2

stderr은 IO Cache 버퍼링을 수행하지 않으므로 응용 프로그램이 중요한 메시지 정보 (일부 오류, 예외)를 콘솔 또는 파일로 인쇄 해야하는 경우 stdout을 사용하여 IO 캐시 버퍼링을 사용하는 것처럼 일반 로그 정보를 인쇄하는 경우 파일 응용 프로그램에 메시지를 작성하기 전에 디버깅 복잡함이 남을 수 있습니다.


0

관련 버퍼링이있는 파일을 스트림이라고하며 정의 된 유형 FILE에 대한 포인터로 선언됩니다. fopen () 함수는 스트림에 대한 특정 설명 데이터를 작성하고 모든 추가 트랜잭션에서 스트림을 지정하기위한 포인터를 리턴합니다. 일반적으로 헤더에 상수 포인터가 선언되고 표준 열린 파일과 연관된 세 개의 열린 스트림이 있습니다. 프로그램 시작시 3 개의 스트림이 미리 정의되어 있으며 표준 입력 (일반 입력 읽기 용), 표준 출력 (일반 출력 쓰기 용) 및 표준 오류 (진단 출력 쓰기 용)가 명시 적으로 열 필요는 없습니다. 열면 표준 오류 스트림이 완전히 버퍼링되지 않습니다. 표준 입력 및 표준 출력 스트림은 대화식 장치를 참조하지 않는 것으로 스트림을 결정할 수있는 경우에만 완전히 버퍼링됩니다.

https://www.mkssoftware.com/docs/man5/stdio.5.asp

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.