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

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

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

예를 들어 에서는 계산 head t.txt -n 5 | tail -n 2head t.txt -n 5다음 tail -n 2이를 실행합니다. 아니면 먼저 3~5행을 읽어야 한다고 쉘에 알리는 추상화가 있습니까? 이 예에서는 차이가 없을 수도 있지만 다른 시나리오에서는 차이가 있을 수 있습니다.

답변1

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

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

$ p1 | p2

이 경우 개념적으로 쉘은 위에서 언급한 파이프 fork()s를 생성하고 자식은 표준 출력 스트림을 파이프의 쓰기 끝 부분에 연결한 다음 자식 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
         └───────────┘ └───────────┘ └─────────────┘

관련 정보