명령에 어떻게 여러 출력이 있을 수 있나요?

명령에 어떻게 여러 출력이 있을 수 있나요?

존재하다이 답변맨 아래에서 Gilles는 명령에 여러 출력 또는 입력이 있을 수 있다고 언급합니다.

예, 합계를 입력 으로 cat foo bar | something사용 하고 출력으로 사용하는 경우가 있지만 실제로는 그런 뜻이 아닌 것 같습니다.foobartee

프로그램에 어떻게 여러 개의 입력이나 출력이 있을 수 있나요?

답변1

cat foo bar예는 제가 의도한 것이 아닙니다. cat한 번에 하나의 입력과 하나의 출력만 있습니다 .

tee예를 들면 다음과 같습니다. 모든 인수와 표준 출력으로 출력합니다. 에서와 동일한 유형의 ASCII 아트를 사용하십시오.내 이전 답변, tee foo bar터미널에서 실행했을 때의 모습입니다.

   +------------------+    
   |       tee        |    
===|<stdin            |         +------------+
→  |                  |         |  terminal  |
   |           stdout>|=========|<input      |
   |                  |   → ##==|<           |
   |                  |     ||  +------------+
   |           stderr>|=====##
   |                  |   →
   |                  |       +-------------+
   |                3>|=======|> file "foo" |
   |                  |   →   +-------------+
   |                  |       +-------------+
   |                4>|=======|> file "bar" |
   |                  |   →   +-------------+
   |                  |    
   +------------------+    

이 예에서 tee"유용한" 출력은 세 가지 채널, 즉 터미널(표준 출력이 연결되는 곳이기 때문에)과 두 개의 파일로 전송됩니다. 또한 tee추가 오류 출력 채널이 있습니다.

프로그램에는 일반적으로 채널로 식별되는 세 개의 입력/출력 채널이 있습니다.파일 설명자숫자:

  • 표준 입력(간단히 stdin, 파일 설명자 0);
  • 표준 출력(stdout, 파일 설명자 1이라고 함)
  • 표준 오류(간단히 stderr, 파일 설명자 번호 2).

파일 설명자 0, 1, 2의 목적은 단순히 규칙의 문제입니다. 프로그램이 파일 설명자 0에 쓰거나 설명자 1과 2에서 읽을 수 없도록 강제하는 것은 없지만 거의 보편적으로 따르는 규칙입니다.

터미널에서 프로그램을 실행하는 경우 파일 설명자 0, 1, 2는 리디렉션되지 않는 한 처음에 터미널에 연결됩니다. 다른 파일 설명자는 처음에 닫히고 프로그램이 다른 파일을 열 때 사용됩니다.

특히 모든 명령에는 표준 출력(명령의 페이로드, "유용한" 출력)과 표준 오류(오류 또는 정보 메시지)의 두 가지 출력이 있습니다.

쉘( command1 | command2 | command3 | …)의 파이프는 각 명령의 표준 출력을 다음 명령의 표준 입력에 연결합니다. 모든 명령에 대한 표준 오류는 리디렉션되지 않는 한 터미널로 전송됩니다.

셸은 다른 파일 설명자를 리디렉션하는 방법을 제공합니다. 표준 오류가 발생했거나 리디렉션 2>&1되었을 수 있습니다 . 2>file바라보다 추가 파일 설명자는 언제 사용됩니까?또 다른 게시물은 다른 파일 설명자의 조작 예에 대한 링크입니다.

기능이 풍부한 쉘은 또한 다음을 제공합니다.프로세스 교체명령당 단일 입력과 단일 출력이 있는 선형 파이프라인으로 제한되지 않도록 파이프라인 명령에 대한 파일 리디렉션을 일반화합니다.

파일을 열지 않는 한 2보다 큰 파일 설명자에 액세스하려고 시도하는 명령은 거의 없습니다. 파일을 열면 무료 파일 설명자가 선택되고 해당 번호가 응용 프로그램에 반환됩니다. 예를 들어 GnuPG는 표준 입력에서 암호화/해독/서명/검증을 위해 데이터를 읽고 결과를 표준 출력에 기록할 것으로 예상합니다. 이 옵션을 사용하여 다른 파일 설명자에서 비밀번호를 읽도록 지시할 수 있습니다 --passphrase-fd. GnuPG에는 다른 파일 설명자에 대한 상태 데이터를 보고하는 옵션도 있으므로 stdout에 페이로드를 출력하고 stderr에 오류 메시지를 출력하고 다른 파일 설명자에 대한 상태 정보를 얻을 수 있습니다. 다음은 파이프된 명령의 출력을 비밀번호로 사용하는 예입니다.

echo fjbeqsvfu | rot13 | gpg -d --passphrase-fd=3 3<&0 <file.encrypted >file.plaintext

답변2

명령은 여러 출력 스트림을 가질 수 있습니다. 파일이나 소켓에 쓰는 것을 의미하는 것은 아닙니다. 대부분의 GNU 도구(예: grep)는 오류를 stderr로 인쇄하고 예상되는 출력을 stdout으로 인쇄한다는 점을 고려하십시오. 둘 다 대화형 셸(2>&1)에 병합되지만 여전히 별도로 처리할 수 있습니다. 프로그램이나 코드 블록이 지원하는 경우 추가 파일 설명자를 사용할 수 있으므로 여기서 끝나지 않습니다.

고안된 예:

{
  grep NORMAL log.txt
  grep WARN log.txt 1>&3
  grep ERROR log.txt 1>&4
} 1> normals.txt 3> warnings.txt 4> errors.txt # 2>/dev/null

답변3

예. 예를 들어, cat foo bar | less두 개의 입력(file foo 및 file bar)이 주어지고 둘 다 less로 출력합니다. vim foo*foo로 시작하는 모든 파일은 vim으로 출력됩니다. 각 파일을 본 후 :n(또는 변경한 경우 :wn)을 사용하여 다음 출력으로 전환할 수 있습니다. 나는 Giles가 그것을 잘 설명했다고 생각합니다. 파이프( | )를 사용하면 한 명령의 출력을 가져와 다른 명령에 입력한 다음 결과를 인쇄합니다. 이는 다중 출력의 또 다른 예입니다.

관련 정보