문제

bash가 파이프를 통해 데이터 전송을 처리하는 방법을 아는 사람이 있습니까?

cat file.txt | tail -20

이 명령은 file.txt의 모든 내용을 버퍼에 인쇄한 다음 tail로 읽습니까?아니면 이 명령은 file.txt의 내용을 한 줄씩 인쇄한 다음 꼬리가 처리되도록 각 줄에서 일시 중지하고 더 많은 데이터를 요청합니까?

내가 묻는 이유는 기본적으로 일부 데이터 덩어리에 대해 일련의 작업을 수행하는 임베디드 장치에서 한 작업의 출력이 다음 작업의 입력으로 전송되는 프로그램을 작성하고 있기 때문입니다.Linux(bash)가 이를 어떻게 처리하는지 알고 싶습니다. "cat file.txt | tail -20"을 실행할 때 구체적으로 어떤 일이 발생하는지가 아닌 일반적인 답변을 제공해 주시기 바랍니다.

귀하의 답변에 미리 감사드립니다!

편집하다:Shog9는 관련 Wikipedia 기사를 지적했는데, 이 기사가 바로 해당 기사로 연결되지는 않았지만 다음을 찾는 데 도움이 되었습니다. http://en.wikipedia.org/wiki/Pipeline_%28Unix%29#Implementation 내가 찾고 있던 정보가 들어 있었네요.


제 자신을 명확하게 밝히지 못해 죄송합니다.물론 파이프를 사용하고 있으며 명령의 각 부분에 대해 stdin 및 stdout을 사용하고 있습니다.나는 그것이 너무 명백해서 진술할 수 없다고 생각했습니다.

내가 묻는 것은 이것이 어떻게 처리/구현되는지입니다.두 프로그램을 동시에 실행할 수 없으므로 stdin에서 stdout으로 데이터가 어떻게 전송됩니까?첫 번째 프로그램이 두 번째 프로그램보다 훨씬 빠르게 데이터를 생성하면 어떻게 되나요?시스템은 종료되거나 stdout 버퍼가 가득 찰 때까지 첫 번째 명령을 실행한 다음 처리할 데이터가 더 이상 남지 않을 때까지 루프에서 다음 프로그램으로 이동합니까, 아니면 더 복잡한 메커니즘이 있습니까? ?

도움이 되었습니까?

해결책

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

여기서 "마법"은 운영 체제에 있습니다.두 프로그램 모두 거의 동시에 시작되고 컴퓨터에서 동시에 실행되는 다른 모든 프로세스(터미널 응용 프로그램 및 커널 포함)와 마찬가지로 동시에 실행됩니다(운영 체제는 프로세서에서 실행할 시간을 할당합니다). .따라서 데이터가 전달되기 전에 프로세스는 필요한 모든 초기화를 수행합니다.귀하의 예에서 tail은 '-20' 인수를 구문 분석하고 cat은 'file.txt' 인수를 구문 분석하고 파일을 엽니다.어느 시점에서 tail은 입력이 필요한 지점에 도달하고 운영 체제에 입력을 기다리고 있음을 알립니다.다른 시점(이전이나 이후는 중요하지 않음)에서 cat은 stdout을 사용하여 운영 체제에 데이터를 전달하기 시작합니다.이는 운영 체제의 버퍼로 들어갑니다.다음 타임 테일은 일부 데이터가 cat에 의해 버퍼에 입력된 후 프로세서에서 타임 슬라이스를 가져오며 운영 체제에 버퍼를 남기는 해당 데이터의 일부(또는 전체)를 검색합니다.버퍼가 비어 있으면 어떤 시점에서 tail은 cat이 더 많은 데이터를 출력할 때까지 기다려야 합니다.cat이 tail이 처리하는 것보다 훨씬 빠르게 데이터를 출력하면 버퍼가 확장됩니다.cat은 결국 데이터 출력을 완료하지만 tail은 여전히 ​​처리 중이므로 cat이 닫히고 tail은 버퍼에 남아 있는 모든 데이터를 처리합니다.운영 체제는 더 이상 EOF로 들어오는 데이터가 없을 때 tail 신호를 보냅니다.Tail은 나머지 데이터를 처리합니다.이 경우 tail은 아마도 모든 데이터를 20라인의 순환 버퍼로 수신하고 운영 체제에서 더 이상 들어오는 데이터가 없다는 신호를 받으면 마지막 20라인을 자체 stdout에 덤프합니다. 그냥 터미널에 표시됩니다.tail은 cat보다 훨씬 간단한 프로그램이므로 cat이 데이터를 버퍼에 넣을 때까지 기다리는 데 대부분의 시간을 소비할 가능성이 높습니다.

다중 프로세서가 있는 시스템에서 두 프로그램은 동일한 프로세서 코어에서 교대로 시간 조각을 공유할 뿐만 아니라 별도의 코어에서 동시에 실행될 가능성이 높습니다.

좀 더 자세히 알아보려면 Linux에서 'top'과 같은 일종의 프로세스 모니터(운영 체제별)를 열면 실행 중인 프로세스의 전체 목록을 볼 수 있으며, 그 중 대부분은 실제로 프로세서의 0%를 사용하고 있습니다.대부분의 애플리케이션은 데이터를 처리하는 경우를 제외하고는 대부분의 시간을 아무것도 하지 않는 데 소비합니다.이는 다른 프로세스가 필요에 따라 프로세서에 자유롭게 액세스할 수 있도록 하기 때문에 좋습니다.이는 기본적으로 세 가지 방법으로 수행됩니다.프로세스는 기본적으로 커널에 작업할 다른 시간 조각을 제공하기 전에 n 밀리초를 기다리라고 지시하는 sleep(n) 스타일 명령에 도달할 수 있습니다.가장 일반적으로 프로그램은 더 많은 데이터가 버퍼에 들어갈 때까지 기다리는 'tail'과 같이 다른 프로그램의 무언가를 기다려야 합니다.이 경우 운영 체제는 더 많은 데이터를 사용할 수 있을 때 프로세스를 깨웁니다.마지막으로, 커널은 실행 중에 프로세스를 선점하여 일부 프로세서 시간 조각을 다른 프로세스에 제공할 수 있습니다.'cat'과 'tail'은 간단한 프로그램입니다.이 예에서 tail은 버퍼에서 더 많은 데이터를 기다리는 데 대부분의 시간을 보내고, cat은 운영 체제가 하드 드라이브에서 데이터를 검색할 때까지 기다리는 데 대부분의 시간을 보냅니다.병목 현상은 파일이 저장되는 물리적 매체의 속도(또는 느림)입니다.이 명령을 처음 실행할 때 감지할 수 있는 지연은 디스크 드라이브의 읽기 헤드가 'file.txt'가 있는 하드 드라이브의 위치를 ​​찾는 데 걸리는 시간입니다.명령을 두 번째로 실행하면 운영 체제는 file.txt의 내용을 메모리에 캐시할 가능성이 높으며, file.txt가 매우 크거나 파일이 더 이상 캐시되지 않는 한 눈에 띄는 지연이 발생하지 않을 것입니다. .)

컴퓨터에서 수행하는 대부분의 작업은 IO 바인딩되어 있습니다. 즉, 일반적으로 하드 드라이브나 네트워크 장치 등에서 데이터가 오기를 기다리고 있음을 의미합니다.

다른 팁

Shog9는 이미 Wikipedia 기사를 참조했지만 구현 섹션 원하는 세부정보가 있습니다.기본 구현은 제한된 버퍼입니다.

cat은 데이터를 표준 출력으로 인쇄하고, 이는 tail의 표준 입력으로 리디렉션됩니다.이는 bash 맨페이지에서 확인할 수 있습니다.

즉, 일시 중지가 진행되지 않고 tail은 표준 입력에서 읽고 cat은 표준 출력에 쓰는 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top