Bash 파이프 처리


29

bash가 파이프를 통해 데이터를 보내는 방법을 아는 사람 있습니까?

이 명령은 file.txt의 모든 내용을 버퍼에 인쇄하고 꼬리로 읽습니까? 또는이 명령은 file.txt의 내용을 줄 단위로 인쇄 한 다음 각 줄에서 일시 중지하여 처리하고 더 많은 데이터를 요구합니까?

내가 묻는 이유는 기본적으로 한 작업의 출력이 다음 작업의 입력으로 보내지는 데이터 청크에서 일련의 작업을 수행하는 임베디드 장치에 프로그램을 작성하고 있기 때문입니다. 나는 리눅스 (bash)가 이것을 어떻게 처리하는지 알고 싶다. 그래서 나는 "cat file.txt | tail -20"을 실행할 때 어떤 일이 발생하지 않았는지에 대한 일반적인 대답을 알려주고 싶다.

미리 답변 해 주셔서 감사합니다.

EDIT : Shog9는 관련 위키피디아 기사를 지적했으나 기사에 직접 연결되지는 않았지만 내가 찾던 정보를 찾는데 도움이되었습니다. http://en.wikipedia.org/wiki/Pipeline_%28Unix%29#Implementation에는 내가 원하는 정보가있었습니다.


자신을 분명히하지 못해 죄송합니다. 물론 파이프를 사용하고 있으며 명령의 각 부분에 대해 stdin과 stdout을 사용하고 있습니다. 나는 그것이 너무 명백한 상태라고 생각했다.

나는 이것이 어떻게 처리되고 구현되는지를 묻고있다. 두 프로그램은 동시에 실행할 수 없으므로 데이터는 표준 입력에서 표준 출력으로 어떻게 전송됩니까? 첫 번째 프로그램이 두 번째 프로그램보다 훨씬 빠른 데이터를 생성하면 어떻게됩니까? 시스템이 종료되거나 stdout 버퍼가 꽉 찼을 때까지 첫 번째 명령을 실행합니까? 다음 프로그램으로 넘어갑니다. 처리 할 데이터가 더 이상 남아 있지 않거나 더 복잡한 메커니즘이있을 때까지 반복합니다. ?

54

좀 더 자세한 설명을하기로 결심했습니다.

"마법"은 운영 체제에 있습니다. 두 프로그램 모두 거의 동시에 시작되어 동시에 실행됩니다 (운영 체제는 프로세서에서 실행 시간 조각을 할당하여 실행 함) 동시에 컴퓨터에서 실행되는 모든 프로세스 (터미널 응용 프로그램 및 커널 포함) . 따라서 모든 데이터가 전달되기 전에 프로세스는 필요한 초기화 작업을 수행합니다. 귀하의 예제에서 꼬리는 '-20'인수를 파싱하고 cat은 'file.txt'인수를 파싱하고 파일을 여는 중입니다. 어떤 지점에서 꼬리는 입력이 필요한 시점에 도달하고 운영 체제가 입력을 기다리고 있다고 알립니다. 어떤 다른 시점 (앞이나 뒤에, 중요하지 않음)에서 cat은 stdout을 사용하여 운영 체제로 데이터를 전달하기 시작할 것입니다. 이것은 운영 체제의 버퍼로 이동합니다. 다음에 꼬리는 일부 데이터가 cat에 의해 버퍼에 저장 된 후 프로세서에서 시간 조각을 얻으면 운영 체제에서 버퍼를 벗어나는 일부 데이터 (또는 모든 데이터)를 검색합니다. 버퍼가 비어 있으면 어떤 지점에서 꼬리는 고양이가 더 많은 데이터를 출력 할 때까지 기다려야합니다. 고양이가 꼬리가 데이터를 처리하는 것보다 훨씬 빠르게 데이터를 출력하는 경우 버퍼가 확장됩니다.cat은 결국 데이터를 출력하지만 꼬리는 계속 처리되므로 고양이가 닫히고 꼬리가 버퍼의 나머지 모든 데이터를 처리합니다. 운영 체제는 EOF가있는 수신 데이터가 더 이상 없을 때 신호를 보냅니다. Tail은 나머지 데이터를 처리합니다. 이 경우, 꼬리는 아마도 모든 데이터를 20 라인의 순환 버퍼에 수신하는 것일 뿐이고, 수신 데이터가 더 이상 없다고 운영 시스템에서 신호를 받으면 마지막 20 라인을 자체 stdout으로 덤프합니다. 터미널에 표시됩니다. tail은 cat보다 훨씬 간단한 프로그램이므로 cat이 버퍼에 데이터를 넣길 기다리는 데 대부분 시간을 할애 할 것입니다.

여러 프로세서가있는 시스템에서 두 프로그램은 동일한 프로세서 코어에서 시간 슬라이스를 번갈아 가며 동시에 다른 코어에서 동시에 실행될 수 있습니다.

Linux에서 '최상위'와 같은 프로세스 모니터 (예 : 특정 시스템)를 열면 실행중인 프로세스의 전체 목록을 볼 수 있습니다. 대부분의 프로세스는 0 %의 프로세서. 대부분의 응용 프로그램은 데이터를 처리하지 않는 한 대부분의 시간을 보내지 않습니다. 이것은 다른 프로세스가 필요에 따라 프로세서에 자유롭게 액세스 할 수있게 해주기 때문에 유용합니다. 이것은 기본적으로 세 가지 방법으로 수행됩니다. 프로세스는 sleep (n) 스타일 명령어를 얻을 수 있는데, 기본적으로 커널에게 n 개의 밀리 초를 기다렸다가 다른 타임 슬라이스와 함께 작업하도록 명령합니다. 일반적으로 프로그램은 버퍼에 들어가기 위해 더 많은 데이터를 기다리는 '꼬리'와 같은 다른 프로그램에서 기다려야합니다. 이 경우 운영 체제는 더 많은 데이터를 사용할 수있을 때 프로세스를 시작합니다. 마지막으로, 커널은 실행 중간에 프로세스를 선점하여 다른 프로세스에 일부 프로세서 시간 조각을 제공 할 수 있습니다. '고양이'와 '꼬리'는 간단한 프로그램입니다. 이 예제에서 tail은 버퍼에서 더 많은 데이터를 기다리는 대부분의 시간을 보내며, cat은 운영 체제가 하드 드라이브에서 데이터를 검색하기를 기다리는 대부분의 시간을 보냅니다. 병목 현상은 파일이 저장된 실제 매체의 속도 (또는 느려짐)입니다. 처음으로이 명령을 실행할 때 감지 할 수있는 지각 가능한 지연은 디스크 드라이브의 읽기 헤드가 'file.txt'가있는 하드 드라이브의 위치를 ​​찾는 데 걸리는 시간입니다. 두 번째로 명령을 실행하면 운영 체제의 file.txt 내용이 메모리에 캐시되어 파일 크기가 매우 크거나 파일이 더 이상 캐시되지 않으면 인식 가능한 지연이 나타나지 않을 것입니다 .)

컴퓨터에서 수행하는 대부분의 작업은 IO 바운드입니다. 즉, 일반적으로 하드 드라이브 나 네트워크 장치 등에서 데이터를 기다리는 중입니다.


0

cat은 데이터를 표준 출력으로 인쇄합니다.이 표준 출력은 꼬리 표준으로 리디렉션됩니다. 이것은 bash의 맨 페이지에서 볼 수 있습니다.

다른 말로하면, 일시 중지가없고, 꼬리는 표준에서 읽는 것이며 고양이는 표준 출력에 쓰는 중입니다.


1

Shog9는 이미 위키 백과 문서를 참조했지만 implementation section에 원하는 세부 정보가 있습니다. 기본 구현은 제한된 버퍼입니다.