예를 들어 파이프를 사용할 때
sudo cat /dev/sda | strings | less
SDA 장치의 문자열 내에서 이동할 수 있습니다. 그런데 sda 장치의 내용이 완전히 로드되어 고양이의 출력 스트림으로 출력됩니까? 아니면 프로그램이 cat의 출력을 요청할 때마다 개행 문자가 평가됩니까? (즉, 적은 호출기에서 j를 누릅니다)
답변1
이것은 HOW 나 작업 less
보다는 HOW와 더 관련이 있습니다 .cat
strings
이 cat
명령은 데이터를 표준 출력으로 푸시하며, strings
그 사이의 파이프 버퍼가 가득 차고 아무도 읽지 않는 한 차단됩니다. cat
자체적으로 최소한의 버퍼링을 수행하며 파이프 버퍼는 일반적으로 작습니다.
에 대해서도 마찬가지입니다 strings
. 결과 데이터가 읽히지 않으면 들어오는 데이터를 처리하고 cat
차단 합니다.less
strings
less
해당 입력은 표시되는 데이터에서 앞뒤로 이동할 수 있도록 버퍼링됩니다. 다음 페이지로 스크롤하면 해당 버퍼에서 less
더 많은 데이터를 읽습니다 . strings
앞으로 스크롤하지 않으면 less
제한된 양의 데이터만 읽힐 것이라고 생각합니다(그래서 앞으로 스크롤하지 않으면 차단됩니다) strings
.cat
많은 양의 데이터가 파이프로 연결되면 less
버퍼링에 많은 양의 메모리가 사용됩니다.만약에당신은 그것을 모두 읽기로 결정했습니다 less
.
-B
버퍼링에 사용되는 메모리 양을 64KB(또는 -b
해당 옵션으로 지정한 크기) 로 제한하는 옵션이 있습니다 . 이러한 방식으로 버퍼 크기를 제한하면 지정된 버퍼 공간에 저장할 수 있는 것보다 더 많이 뒤로 스크롤하는 것을 방지할 수 있을 뿐만 아니라 less
메모리 부족 없이 많은 양의 데이터를 읽을 수 있습니다 .
또한 man less
시스템을 참조하십시오.
답변2
파이프에는 버퍼 공간이 제한되어 있으며 파이프 판독기(예 less
: 예제)가 파이프에서 더 많은 데이터를 읽지 않으면 기록기는 버퍼를 채운 후 차단됩니다. 이는 strings
명령 에 영향을 미치며 cat
파이프가 가득 차면 명령을 차단합니다.
물론 이 cat
명령으로는 sda 장치의 전체 내용을 메인 메모리로 읽어올 수는 없으므로 아직 읽지 않은 블록이 변경되면 cat
변경된 내용을 보게 됩니다.
답변3
그리고 cat
대부분의 strings
유사한 유틸리티에서는 한 번에 약간의 입력을 읽고 처리한 다음 더 많은 입력을 읽는 등의 작업을 수행합니다. 따라서 귀하의 경우에는 표시된 내용과 전송되는 내용 중 일부만 읽혀집니다 cat
.less
더 자세히 살펴보면 기본 작업은 다음 cat
과 같습니다.
- 몇 킬로바이트의 메모리가 버퍼로 사용되도록 예약되어 있습니다.
- 사용할 수 있는 입력이 더 많지만 다음과 같습니다.
- 최대 N바이트의 입력을 버퍼로 읽습니다. (이전 사이클에 기록된 데이터를 덮어쓰게 됩니다.)
- 출력에 버퍼 내용을 씁니다.
출력을 복사할 위치가 있을 때까지 쓰기 작업이 차단됩니다. 파이프가 출력할 때 파이프 자체는 커널에서 약간의 메모리를 소비합니다.파이프 버퍼. 가득 차면 cat
파이프에 쓰기를 시도하면 공간을 사용할 수 있을 때까지 쓰기 시도가 차단됩니다. 파이프의 읽기 측 프로세스가 일부 데이터를 읽을 때 파이프 버퍼에 공간이 있을 수 있습니다.
이 프로그램은 전체 입력을 복사하지 않고 선택한 부분만 복사한다는 점을 제외하면 strings
와 동일한 방식으로 작동합니다 .cat
이 less
프로그램은 약간 다르게 작동합니다. 읽은 모든 내용을 메모리에 보관합니다. 버퍼를 재활용하지 않고, 더 많은 입력이 계속 들어오는 한 계속해서 버퍼를 증가시킵니다. 그러나 읽기 부분은 less
필요할 때만 데이터를 읽는다는 점에서 비슷합니다. 표시된 마지막 줄과 읽을 것으로 예상되는 줄까지만 읽습니다.
따라서 를 실행하면 sudo cat /dev/sda | strings | less
읽혀지는 내용은 /dev/sda
다음과 같습니다.
less
데이터가 표시되거나 스크롤되어 지나갔습니다.less
읽었지만 아직 표시되지 않은 데이터는 최대 몇 kB입니다.strings
와 사이의 파이프 버퍼는 최대 몇 kB입니다less
.- 메모리 용량은 최대 몇 kB까지 가능합니다
strings
. cat
와 사이의 파이프 버퍼는 최대 몇 kB입니다strings
.- 메모리 용량은 최대 몇 kB까지 가능합니다
cat
.
시스템 호출을 추적하여 각 프로그램이 데이터를 읽고 쓰는 시기를 관찰할 수 있습니다.
sudo strace -e read,write -o cat.strace cat /dev/sda | strace -e read,write -o cat.strace strings | strace -e read,write -o less.strace less
그리고 *.strace
파일을 보세요. 예를 들어 where is 를 사용하거나 프로세스 ID를 사용하여 cat
파일 오프셋을 확인하여 읽은 데이터의 양을 확인할 수도 있습니다 .lsof -p1234
head /proc/1234/fdinfo/0
1234
cat
1 기본 텍스트 처리 유틸리티에서 주요 예외는 sort
전체 입력을 읽을 때까지 출력을 내보낼 수 없다는 것입니다. 아는 한 출력의 첫 번째 줄은 도달한 입력의 마지막 줄일 가능성이 높습니다.
답변4
일부 시스템(예: MS-Dos)에서는 첫 번째 명령의 출력을 파일에 복사한 다음 두 번째 명령을 실행하여 해당 파일에서 읽는 방식으로 파이프가 구현됩니다. 유닉스는 이런 일을 하지 않는다.
Unix에서는 생산 라인과 같습니다. 각 단계는 동시에 작동하여 입력을 읽고 출력을 생성합니다. 프로세스 A가 프로세스 B가 소비하는 것보다 빠르게 생산하면 프로세스 A와 B 사이에 재고가 축적됩니다. 인벤토리가 너무 많으면(½KiB ~ 4KiB) 프로세스 A가 일시 중지됩니다. B가 처리할 재고가 없으면 B는 일시 중지됩니다. 재고 수준을 낮게 유지하기 위해 프로세스가 일시 중지되거나 일시 중지 해제됩니다.
이 프로그램의 코드는 그것에 대해 신경 쓰지 않습니다. 단지 입력을 읽고 출력을 씁니다. 데이터를 사용할 수 있기 전에 읽으려고 하거나 다음 프로세스가 준비되기 전에 쓰려고 하면 운영 체제는 준비될 때까지 이를 일시 중지합니다.
더 이상 읽을 내용이 없고 더 이상 읽고 있는 내용도 없으면 리더는 파일 끝을 수신하고 종료됩니다. 그러면 다음 프로세스에서 파일 끝이 트리거됩니다.