Bash 명령의 파이프는 어떻게 작동합니까?

Bash 명령의 파이프는 어떻게 작동합니까?

파이프를 통해 bash 명령을 연결할 때 상징적인 일이 발생합니까, 아니면 모두 계산-통과-계산-통과입니까?

예를 들어 에서는 head t.txt -n 5 | tail -n 2계산 head t.txt -n 5한 다음 tail -n 2실행합니다. 아니면 먼저 쉘에 3~5행을 읽도록 지시하는 추상화가 있습니까? 아마도 이 예에서는 차이가 없을 것 같지만 다른 경우에는 차이가 있을 것 같습니다.

답변1

셸은 pipe(2)시스템 호출을 사용하여 두 개의 파일 설명자가 있는 커널에 제한된 버퍼를 생성합니다. 하나는 프로세스가 버퍼에 쓸 수 있게 하고 다른 하나는 프로세스가 버퍼에서 읽을 수 있도록 합니다.

간단한 경우를 생각해 보십시오:

$ p1 | p2

이 경우 개념적으로 쉘은 위의 파이프 fork()를 생성하고 자식은 표준 출력 스트림을 파이프의 쓰기 끝에 연결한 다음 자식 exec()s를 연결합니다 p1. 다음으로, 쉘은 fork()다시 s 이고, 자식은 표준 입력 스트림을 파이프의 읽기 끝에 연결한 다음 자식 exec()s 에 연결합니다 p2. (나는 말했다개념적으로쉘은 다른 순서로 작업을 수행할 수 있지만 아이디어는 동일하기 때문입니다. )

그 당시에 p1는 와 p2동시에 실행 중이었습니다. p1파이프에 기록되고 커널은 기록된 데이터를 버퍼에 복사합니다. p2파이프에서 읽고 커널은 버퍼에서 읽은 데이터를 복사합니다. 파이프가 가득 차면 커널은 파이프에서 무언가를 읽을 때까지 p1호출을 차단하여 일부 공간을 확보합니다. 파이프가 비어 있으면 커널은 파이프에 더 많은 데이터가 기록될 때까지 호출을 차단합니다.write()p2p2read()p1

답변2

추천해주신 두 가지 모델 중 계산된 패스 - 계산된 패스가 가장 가깝습니다. 쉘은 단지 연결 프로세스일 뿐입니다. 그들이 무엇을 하고 있는지 전혀 모릅니다.

와는 별개로, 실행 순서는 정의되지 않습니다. 그들은 실제로 동시에 실행됩니다. 그러나 왼쪽에 있는 것이 먼저 바이트를 출력하고 오른쪽에 있는 것이 바이트를 입력해야 합니다. 데이터는 왼쪽에서 오른쪽으로 흐릅니다. 데이터는 첫 번째 명령에서 표준 출력으로 흐른 다음 다음 프로세스의 표준 입력으로 이동하고 그곳에서 처리된 다음 표준 출력에서 ​​나오고 다른 프로세스로 파이프될 수 있습니다.

리디렉션 등을 사용하지 않거나 >파일 <에서 읽지 않습니다. 그러면 다음과 같습니다.

         ┌───────────┐ ┌───────────┐ ┌─────────────┐
Terminal⇨│Process one│⇨│Process two│⇨│Process Three│⇨Terminal
         └───────────┘ └───────────┘ └─────────────┘

관련 정보