터미널에서 몇 가지 명령을 실행하고 있었기 때문에 파이프 명령을 실행할 때 Unix / Linux가 단축키를 사용합니까?
예를 들어 백만 줄의 파일이 있고 그중 첫 10 줄에 포함되어 있다고 가정 해 봅시다 hello world
. 명령을 실행하면 grep "hello world" file | head
10 행을 찾 자마자 첫 번째 명령이 중지되거나 전체 파일을 먼저 계속 탐색합니까?
답변
일종의. 쉘은 실행중인 명령이 무엇인지 알지 못하고 단지 하나의 출력을 다른 것의 입력에 연결합니다.
경우 grep
발견 후 “안녕하세요 세계를”말보다 10 개 라인은 head
가까운 파이프가 원하는 모든 10 개 라인을 가지고, 그리고 것입니다. grep
SIGPIPE로 인해 종료 될 수 있으므로 매우 큰 파일을 계속 스캔 할 필요는 없습니다.
답변
프로그램이 파이프에 쓰려고 시도하고 해당 파이프에서 프로세스를 읽을 수없는 경우 기록기 프로그램은 SIGPIPE 신호를 수신합니다 . 프로그램이 SIGPIPE를 수신 할 때 기본 조치는 프로그램을 종료하는 것입니다. 프로그램은 SIGPIPE 신호를 무시하도록 선택할 수 있으며이 경우 쓰기는 오류 ( EPIPE
)를 반환합니다 .
귀하의 예에서는 다음과 같은 일정이 있습니다.
grep
및head
명령은 병렬로 시작합니다.grep
입력을 읽고 처리를 시작합니다.- 어떤 시점에서
grep
첫 번째 출력 덩어리를 생성합니다. head
첫 번째 청크를 읽고 씁니다.- 처음 10 개 일치 이후에 충분한 행이 있다고 가정하면 (그렇지 않으면
grep
먼저 종료 될 수 있음) 결국head
원하는 수의 행을 인쇄합니다. 이 시점에서head
종료합니다. grep
및head
프로세스 의 상대 속도에 따라grep
일부 데이터가 누적되어 아직 인쇄되지 않았을 수 있습니다. 시간에head
종료,grep
입력을 읽거나이 계속 그렇게 할 것이다이 경우 내부 처리를 수행 할 수있다.- 곧
grep
처리 된 데이터를 쓸 것입니다. 이 시점에서 SIGPIPE를 받고 죽습니다.
grep
엄격하게 필요한 것보다 약간 더 많은 입력을 처리 할 가능성이 있지만 일반적으로 몇 킬로바이트에 불과합니다.
head
일반적으로 몇 킬로바이트 단위로 읽습니다 (read
각 바이트에 대한 시스템 호출을 발행하는 것보다 효율적이기 때문에이 동작을 버퍼링이라고 함). 따라서 원하는 마지막 행 이후의 나머지 청크는 버려집니다.- 파이프에 커널이 관리하는 관련 버퍼 (대개 512 바이트)가 있으므로 전송중인 일부 데이터가있을 수 있습니다. 이 데이터는 폐기됩니다.
grep
출력 청크가 될 준비가 된 일부 데이터를 축적했을 수 있습니다 (다시 버퍼링). 출력 버퍼를 비우려고 할 때 SIGPIPE를 수신합니다.
모든 시스템에서 필터링 유틸리티가 자연스럽게 효율적으로 작동하도록 정밀하게 설계되었습니다. 출력 채널이 종료 될 때 계속 진행해야하는 프로그램은 SIGPIPE 신호를 무시하는 단계를 수행해야합니다.
답변
Sortof, 파이프 라인은 다음과 같이 작동합니다. 먼저 첫 번째 명령을 실행 한 다음 두 번째 명령을 실행합니다.
즉, A|B
주어진 명령을 보자 . 그럼 여부 불확실 A
하거나 B
처음 시작합니다. CPU가 여러 개인 경우 정확히 동시에 시작할 수 있습니다. 파이프는 정의되지 않았지만 유한 한 양의 데이터를 보유 할 수 있습니다.
B가 파이프에서 읽으려고하지만 사용할 수있는 데이터가 없으면 데이터가 B
도착할 때까지 기다립니다. B
디스크에서 읽은 경우 B
동일한 문제가 발생하여 디스크 읽기가 완료 될 때까지 기다려야합니다. 더 가까운 비유는 키보드를 읽는 것입니다. 이, B
유형에 사용자를 기다릴 필요가있다. 그러나이 모든 경우에 B는 “읽기”작업을 시작했으며 완료 될 때까지 기다려야합니다. 그러나 B
명령이 부분 출력 만 필요하면 입력 레벨에 도달 A
한 특정 지점 이 SIGPIPE에 의해 종료됩니다.B
A
경우 A
시도가 파이프에 쓸 파이프가 가득, A
무료가 될 파이프의 여지 기다려야합니다. A
터미널에 쓰는 경우에도 같은 문제가 발생할 수 있습니다. 터미널에는 흐름 제어 기능이 있으며 데이터 속도를 조절할 수 있습니다. 어쨌든 to A
는 “쓰기”작업을 시작했으며 쓰기 작업이 완료 될 때까지 기다립니다.
A
및 B
모든 공동 프로세스 파이프와 통신 할 것이지만, 동일 공정으로 행동한다. 어느 쪽도 다른 쪽을 완전히 통제 할 수 없습니다.
답변
grep
파이프를 직접 제어하지 않고 (데이터를 수신하는 중임) 파이프를 직접 제어하지 않고 grep
(데이터를 보내고 있음) …
어떤 grep
다른 프로그램이하는, 또는, 전적으로 그 프로그램 내부 논리입니다. 당신이 말한다면 grep
일찍 만들기 위해 명령 줄 옵션을 통해 발견 된 경우 출구 , 다음은, 그렇지 않으면에 건배 할 것이다 아주 패턴을 찾고 파일의 끝 …
터미널은 내부 작동 grep
및 shell
배관 작업 과 상당히 분리되어 있습니다 … 터미널은 기본적으로 런칭 패드이며 출력 디스플레이입니다 …