Linux에서 stdin, stdout 및 stderr는 무엇입니까?

0
1701
Linux 컴퓨터의 터미널 창
Fatmawati Achmad Zaenuri / Shutterstock.com

stdin, stdout, stderr Linux 명령을 시작할 때 생성되는 세 개의 데이터 스트림입니다. 그것들을 사용하여 스크립트가 파이프 또는 리디렉션되는지 알 수 있습니다. 우리는 당신에게 방법을 보여줍니다.

스트림은 두 지점에 합류

Linux 및 Unix와 같은 운영 체제에 대해 배우기 시작하자마자 용어에 대해 알게 될 것입니다 stdin, stdout, stederr. 이들은 Linux 명령이 실행될 때 설정되는 세 가지 표준 스트림입니다. 컴퓨팅에서 스트림은 데이터를 전송할 수있는 것입니다. 이러한 스트림의 경우 해당 데이터는 텍스트입니다.

물 흐름과 같은 데이터 흐름에는 두 개의 끝이 있습니다. 그들은 소스와 유출이 있습니다. 어떤 Linux 명령을 사용하든 각 스트림의 한쪽 끝을 제공합니다. 다른 쪽 끝은 명령을 시작한 셸에 의해 결정됩니다. 해당 끝은 명령을 시작한 명령 줄에 따라 터미널 창에 연결되거나 파이프에 연결되거나 파일 또는 기타 명령으로 리디렉션됩니다.

리눅스 표준 스트림

리눅스에서는 stdin 표준 입력 스트림입니다. 텍스트를 입력으로 받아들입니다. 명령에서 셸로의 텍스트 출력은 stdout (표준 출력) 스트림. 명령의 오류 메시지는 stderr (표준 오류) 스트림.

두 개의 출력 스트림이 있음을 알 수 있습니다. stdoutstderr하나의 입력 스트림 stdin. 오류 메시지와 일반 출력에는 각각 터미널 창으로 전달하는 자체 도관이 있으므로 서로 독립적으로 처리 할 수 ​​있습니다.

스트림은 파일처럼 처리됩니다

거의 모든 다른 것들과 마찬가지로 Linux의 스트림은 마치 파일 인 것처럼 취급됩니다. 파일에서 텍스트를 읽고 파일에 텍스트를 쓸 수 있습니다. 이 두 가지 조치 모두 데이터 스트림과 관련이 있습니다. 따라서 데이터 스트림을 파일로 처리한다는 개념은 그리 신축 적이 지 않습니다.

프로세스와 연관된 각 파일에는이를 식별하기 위해 고유 번호가 할당됩니다. 이것을 파일 디스크립터라고합니다. 파일에서 조치를 수행해야 할 때마다 파일 디스크립터는 파일을 식별하는 데 사용됩니다.

이 값은 항상 stdin, stdout,stderr:

  • 0: stdin
  • 1: 표준 출력
  • 2: stderr

파이프 및 리디렉션에 반응

주제에 대한 다른 사람의 소개를 쉽게하기 위해 일반적인 기술은 간단한 버전의 주제를 가르치는 것입니다. 예를 들어, 문법을 사용하면 규칙이“C 이전을 제외하고 I 이전에 I”라고합니다. 그러나 실제로이 규칙에는 예외를 따르는 경우보다 더 많은 예외가 있습니다.

비슷한 맥락에서 stdin, stdout, stderr 프로세스가 3 개의 표준 스트림이 종료되는 위치를 모르거나 신경 쓰지 않는다는 허용 된 공리를 제거하는 것이 편리합니다. 프로세스가 출력을 터미널로 보내거나 파일로 리디렉션하는지 여부를 처리해야합니까? 입력이 키보드에서 오는지 또는 다른 프로세스에서 입력되는지를 알 수 있습니까?

실제로, 프로세스는 알고 있거나 최소한 확인하기로 선택한 경우 프로세스가 알고 있으며 소프트웨어 작성자가 해당 기능을 추가하기로 결정한 경우 그에 따라 동작을 변경할 수 있습니다.

이 동작의 변화를 매우 쉽게 볼 수 있습니다. 다음 두 명령을 시도하십시오.

ls

터미널 창에서 ls

ls | cat

터미널 창에 ls 출력

그만큼 ls 출력이 다음과 같은 경우 명령이 다르게 작동합니다 (stdout)이 다른 명령으로 파이프되고 있습니다. 그것은 ls 단일 열 출력으로 전환되며 cat. 과 ls 출력이 리디렉션되는 경우 동일한 작업을 수행합니다.

ls > capture.txt

터미널 창에서 ls> capture.txt

cat capture.txt

터미널 창에서 cat capture.txt

stdout 및 stderr 리디렉션

전용 스트림을 통해 오류 메시지를 전달할 수 있다는 이점이 있습니다. 이는 명령의 출력을 리디렉션 할 수 있음을 의미합니다 (stdout)를 파일에 저장했지만 여전히 오류 메시지 (stderr)를 터미널 창에 표시합니다. 필요한 경우 오류가 발생할 때 오류에 대응할 수 있습니다. 또한 오류 메시지가 파일을 오염시키는 것을 막습니다. stdout 로 리디렉션되었습니다.

다음 텍스트를 편집기에 입력하고 error.sh라는 파일에 저장하십시오.

#!/bin/bash

echo "About to try to access a file that doesn't exist"
cat bad-filename.txt

이 명령으로 스크립트를 실행 가능하게 만드십시오.

chmod +x error.sh

스크립트의 첫 번째 줄은 터미널 창에 stdout 흐름. 두 번째 줄은 존재하지 않는 파일에 액세스를 시도합니다. 이를 통해 전달되는 오류 메시지가 생성됩니다 stderr.

이 명령으로 스크립트를 실행하십시오.

./error.sh

터미널 창에서 ./error.sh

두 출력 스트림이 stdoutstderr터미널 창에가 표시되었습니다.

터미널 창의 error.sh 스크립트에서 출력

출력을 파일로 리디렉션 해 봅시다 :

./error.sh > capture.txt

터미널 창에서 ./error.sh> capture.txt

를 통해 전달되는 오류 메시지 stderr 여전히 터미널 창으로 전송됩니다. 파일의 내용을 확인하여 stdout 출력은 파일로 갔다.

cat capture.txt

터미널 창에서 cat capture.txt

의 출력 stdin 예상대로 파일로 리디렉션되었습니다.

터미널 창에서 capture.txt의 내용

그만큼 > 리디렉션 기호 작동 stdout 기본적으로. 숫자 파일 디스크립터 중 하나를 사용하여 리디렉션하려는 표준 출력 스트림을 표시 할 수 있습니다.

명시 적으로 리디렉션하려면 stdout이 리디렉션 명령을 사용하십시오.

1>

명시 적으로 리디렉션하려면 stderr이 리디렉션 명령을 사용하십시오.

2>

다시 테스트 해 보도록하겠습니다. 이번에는 2>:

./error.sh 2> capture.txt

터미널 창에서 ./error.sh 2> capture.txt

오류 메시지가 리디렉션되고 stdout echo 메시지가 터미널 창으로 전송됩니다.

터미널 창에서 ./error.sh 2> capture.txt 출력

capture.txt 파일에 무엇이 있는지 봅시다.

cat capture.txt

터미널 창에서 cat capture.txt

그만큼 stderr 메시지가 예상대로 capture.txt에 있습니다.

터미널 창에서 capture.txt 파일의 내용

stdout 및 stderr 모두 리디렉션

물론 우리가 방향을 바꿀 수 있다면 stdout 또는 stderr 서로 독립적으로 파일을 만들려면 동시에 두 파일을 서로 다른 파일로 리디렉션 할 수 있어야합니까?

응 우리는 할 수있어. 이 명령은 stdout capture.txt라는 파일로 stderr error.txt라는 파일로

./error.sh 1> capture.txt 2> error.txt

터미널 창에서 ./error.sh 1> capture.txt 2> error.txt

출력 스트림 (표준 출력 및 표준 오류)이 모두 파일로 경로 재 지정되므로 터미널 창에 가시적 인 출력이 없습니다. 아무 것도 발생하지 않은 것처럼 명령 행 프롬프트로 돌아갑니다.

터미널 창에서 ./error.sh 출력

각 파일의 내용을 확인하십시오.

cat capture.txt
cat error.txt

터미널 창에서 capture.txt 및 error.txt의 내용

stdout 및 stderr을 동일한 파일로 리디렉션

깔끔하게, 우리는 각각의 표준 출력 스트림을 자체 전용 파일로 옮겼습니다. 우리가 할 수있는 유일한 조합은 stdoutstderr 같은 파일에.

다음 명령으로이를 달성 할 수 있습니다.

./error.sh > capture.txt 2&>1

세분화합시다.

  • ./error.sh: error.sh 스크립트 파일을 시작합니다.
  • > capture.txt: 리디렉션 stdout capture.txt 파일로 스트리밍하십시오. > 속기 1>.
  • 2> & 1: &> 리디렉션 명령을 사용합니다. 이 명령을 사용하면 하나의 스트림을 다른 스트림과 동일한 대상으로 만들도록 쉘에 지시 할 수 있습니다. 이 경우에는 '리디렉트 스트림 2, stderr, 스트림 1과 동일한 목적지로 stdout님이 리디렉션 중입니다.”

터미널 창에서 ./error.sh> capture.txt 2 &> 1

가시적 인 출력이 없습니다. 고무적입니다.

터미널 창에서 ./error.sh 출력

capture.txt 파일을 확인하고 파일 내용을 살펴 보겠습니다.

cat capture.txt

터미널 창에서 capture.txt의 내용

둘 다 stdoutstderr 스트림이 단일 대상 파일로 리디렉션되었습니다.

스트림의 출력을 재지 정하고 자동으로 버리려면 출력을 /dev/null.

스크립트 내에서 리디렉션 감지

우리는 어떤 스트림이 리디렉션되는지 명령이 어떻게 감지하고 그에 따라 동작을 변경하도록 선택할 수 있는지 논의했습니다. 우리 자신의 스크립트에서 이것을 달성 할 수 있습니까? 응 우리는 할 수있어. 그리고 이해하고 사용하는 것은 매우 쉬운 기술입니다.

편집기에 다음 텍스트를 입력하고 input.sh로 저장하십시오.

#!/bin/bash

if ( -t 0 ); then

  echo stdin coming from keyboard
 
else

  echo stdin coming from a pipe or a file
 
fi

다음 명령을 사용하여 실행 가능하게하십시오.

chmod +x input.sh

영리한 부분은 대괄호 안의 테스트입니다. 그만큼 -t (터미널) 옵션은 파일 디스크립터와 관련된 파일이 터미널 창에서 종료되면 true (0)를 반환합니다. 파일 설명자 0을 테스트의 인수로 사용했습니다. stdin.

만약 stdin 테스트는 터미널 창에 연결되어 있으며 테스트는 사실입니다. 만약 stdin 파일이나 파이프에 연결되어 있으면 테스트가 실패합니다.

편리한 텍스트 파일을 사용하여 스크립트에 입력을 생성 할 수 있습니다. 여기에서는 dummy.txt라는 것을 사용합니다.

./input.sh < dummy.txt

<img class = "alignnone size-full wp-image-436383"src = "https://www.howtogeek.com/wp-content/uploads/2019/08/x26.png.pagespeed.gp+jp+jw+ pj + ws + js + rj + rp + rw + ri + cp + md.ic.KS7TuufRTP.png "alt ="./ input.sh < dummy.txt in a terminal window" width="646" height="57" onload="pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);" onerror="this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);">

출력은 스크립트가 입력이 키보드에서 오는 것이 아니라 파일에서 오는 것을 인식한다는 것을 보여줍니다. 원하는 경우 스크립트의 동작을 적절히 변경할 수 있습니다.

터미널 창의 스크립트 출력

그것은 파일 리디렉션과 관련이 있습니다. 파이프로 시도해 봅시다.

cat dummy.txt | ./input.sh

고양이 dummy.txt | 터미널 창에서 ./input.sh

스크립트는 입력이 파이프되고 있음을 인식합니다. 또는 더 정확하게는 stdin 스트림이 터미널 창에 연결되어 있지 않습니다.

터미널 창에서 스크립트 출력

파이프 나 리디렉션을 사용하지 않고 스크립트를 실행 해 봅시다.

./input.sh

터미널 창에서 ./input.sh

그만큼 stdin 스트림은 터미널 창에 연결되고 스크립트는 이에 따라이를보고합니다.

출력 스트림과 동일한 내용을 확인하려면 새 스크립트가 필요합니다. 편집기에 다음을 입력하고 output.sh로 저장하십시오.

#!/bin/bash

if ( -t 1 ); then

echo stdout is going to the terminal window
 
else

echo stdout is being redirected or piped
 
fi

다음 명령을 사용하여 실행 가능하게하십시오.

chmod +x input.sh

이 스크립트의 중요한 변경 사항은 대괄호 안에있는 테스트입니다. 숫자 1을 사용하여 파일 설명자를 나타냅니다. stdout.

사용해 봅시다. 출력을 통해 파이프하겠습니다 cat.

./output | cat

./output | 터미널 창에 고양이

스크립트는 출력이 터미널 창으로 직접 이동하지 않음을 인식합니다.

터미널 창에서 스크립트 출력

출력을 파일로 리디렉션하여 스크립트를 테스트 할 수도 있습니다.

./output.sh > capture.txt

터미널 창에서 ./output.sh> capture.txt

터미널 창에 출력이 없으면 자동으로 명령 프롬프트로 돌아갑니다. 우리가 기대 한대로

터미널 창에서 스크립트 출력

캡처 된 내용을 확인하기 위해 capture.txt 파일을 살펴볼 수 있습니다. 다음 명령을 사용하십시오.

cat capture.sh

터미널 창에서 cat capture.sh

다시 한번 스크립트의 간단한 테스트는 stdout 스트림이 터미널 창으로 직접 전송되지 않습니다.

파이프 나 리디렉션없이 스크립트를 실행하면 stdout 터미널 창으로 직접 전달됩니다.

./output.sh

터미널 창에서 ./output.sh

그것이 바로 우리가 보는 것입니다.

터미널 창에서 스크립트 출력

의식의 흐름

스크립트가 터미널 창이나 파이프에 연결되어 있는지 또는 리디렉션 중인지 확인하는 방법을 알면 그에 따라 동작을 조정할 수 있습니다.

화면으로 이동하는지 또는 파일로 이동하는지에 따라 로깅 및 진단 출력이 다소 상세 할 수 있습니다. 오류 메시지는 일반 프로그램 출력과 다른 파일에 기록 될 수 있습니다.

일반적으로 그렇듯이 지식이 많을수록 더 많은 옵션이 제공됩니다.