Unix/Linux의 파이프 명령 이해

Unix/Linux의 파이프 명령 이해

두 가지 간단한 프로그램이 있습니다: AB.  A먼저 실행한 다음 B"stdout"을 가져와 A"stdin"으로 사용합니다. GNU/Linux 운영 체제를 사용한다고 가정하면 가장 간단한 방법은 다음과 같습니다.

./A | ./B

이 명령을 설명해야 한다면 A생산자()로부터 입력(읽기)을 받고 소비자( )에 쓰는 B명령 이라고 말하고 싶습니다. 이것이 올바른 설명인가요? 내가 뭐 놓친 거 없니?

답변1

귀하의 질문에서 눈에 띄는 유일한 점은잘못된당신 말이 맞아요

A가 먼저 실행되고 B가 A의 표준 출력을 얻습니다.

사실 두 프로그램은 거의 동시에 시작됐다. 읽으려고 할 때 입력이 없으면 B읽을 입력이 있을 때까지 차단됩니다. 마찬가지로, 아무도 출력을 읽지 않으면 A출력을 읽을 때까지 쓰기가 차단됩니다(일부는 파이프에 의해 버퍼링됨).

파이프라인에 참여하는 프로세스를 동기화하는 유일한 것은 I/O, 즉 파이프라인 전체에서 읽고 쓰는 것입니다. 쓰기나 읽기가 발생하지 않으면 두 프로세스는 완전히 독립적으로 실행됩니다. 한 프로세스가 다른 프로세스의 읽기 또는 쓰기를 무시하면 무시된 프로세스는 차단되어 결국 신호 SIGPIPE(쓰기의 경우)에 의해 종료되거나 다른 프로세스가 조건( 읽는다면).

이를 관용적으로 표현하면 A | B두 개의 프로그램을 포함하는 파이프라인이라는 것입니다. 표준 출력의 첫 번째 프로그램에서 생성된 출력은 표준 입력의 두 번째 프로그램에서 읽을 수 있습니다("[의 출력]은 A[의 입력]으로 파이프됩니다 B"). 쉘은 이를 달성하기 위해 필요한 파이프 작업을 수행합니다.

'소비자', '생산자'라는 단어를 사용하고 싶다면 그것도 괜찮을 것 같아요.

이것이 C로 작성된 프로그램이라는 사실은 부적합합니다. 이것이 Linux, macOS, OpenBSD 또는 AIX라는 사실은 부적합합니다.

답변2

문서에서 일반적으로 사용되는 용어는 하나 이상의 명령으로 구성된 "파이프라인"입니다.POSIX 정의 보기fork()+exec()따라서 기술적으로는 두 개의 명령, 두 개의 셸 하위 프로세스( "외부 명령 사용" 또는 "하위 쉘") 입니다.

에 관해서는생산자-소비자부분적으로 파이프라인은 다음과 같은 이유로 이 패턴으로 설명될 수 있습니다.

  • 생산자와 소비자는 적어도 Linux 및 MacOS X에서는 고정 크기 버퍼를 공유합니다.파이프 버퍼의 고정 크기
  • /proc/<pid>/fd생산자와 소비자는 느슨하게 결합되어 있으며 파이프라인의 명령은 디렉터리를 적극적으로 확인하지 않는 한 서로의 존재를 인식하지 못합니다 .
  • 생산자 쓰기 및 소비자 읽기는 실행되는 단일 명령인 것처럼 stdout기록됩니다 .stdin서로 없이도 존재할 수 있다.

여기서 볼 수 있는 차이점은 다른 언어의 생산자-소비자와 달리 쉘 명령은 버퍼링을 사용하고 버퍼가 가득 차면 stdout에 기록하지만 생산자-소비자가 해당 규칙을 따라야 한다는 언급은 없다는 것입니다. 큐가 가득 차거나 삭제될 때의 데이터(파이프가 수행하지 않는 다른 작업)

관련 정보