파이프 명령을 실행할 때 Linux 유틸리티가 똑똑합니까?


23

터미널에서 몇 가지 명령을 실행하고 있었기 때문에 파이프 명령을 실행할 때 Unix / Linux가 단축키를 사용합니까?

예를 들어 백만 줄의 파일이 있고 그중 첫 10 줄에 포함되어 있다고 가정 해 봅시다 hello world. 명령을 실행하면 grep "hello world" file | head10 행을 찾 자마자 첫 번째 명령이 중지되거나 전체 파일을 먼저 계속 탐색합니까?


2
그것이 바로 gnu grep이 -m논쟁 을하는 이유 입니다.
Paul Tomblin

3
터미널은 그것과 아무 관련이 없습니다. 파이프 된 명령은 셸에서 관리합니다.
Keith Thompson

@KeithThompson 내 무지를 용서하고, 나는 용어에 큰 영향을 미치지 않으며 터미널, 쉘 또는 명령 줄이라고 부를 지 확신하지 못했습니다. 내 질문에 대한 편집을 제안하십시오 :)
DisgruntledGoat

답변:


30

일종의. 쉘은 실행중인 명령이 무엇인지 알지 못하고 단지 하나의 출력을 다른 것의 입력에 연결합니다.

경우 grep발견 후 "안녕하세요 세계를"말보다 10 개 라인은 head가까운 파이프가 원하는 모든 10 개 라인을 가지고, 그리고 것입니다. grepSIGPIPE로 인해 종료 될 수 있으므로 매우 큰 파일을 계속 스캔 할 필요는 없습니다.


2
따라서 경쟁 조건으로 인해 grep은 11 번째 또는 12 번째 패턴을 읽었을 것입니다.
사용자가 알 수 없음

3
이것은 부분적으로 라인의 길이와 파이프 버퍼의 크기에 달려 있지만, 짧은 대답은 grep이 죽이기 전에 합리적으로 제한된 양의 추가 데이터를 읽습니다.
dmckee

1
@userunknown, 정확히.
psusi

쿨, 나는 그것이 일어난 줄 몰랐다. grep/dev/null
Izkata

15

프로그램이 파이프에 쓰려고 시도하고 해당 파이프에서 프로세스를 읽을 수없는 경우 기록기 프로그램은 SIGPIPE 신호를 수신합니다 . 프로그램이 SIGPIPE를 수신 할 때 기본 조치는 프로그램을 종료하는 것입니다. 프로그램은 SIGPIPE 신호를 무시하도록 선택할 수 있으며이 경우 쓰기는 오류 ( EPIPE)를 반환합니다 .

귀하의 예에서는 다음과 같은 일정이 있습니다.

  • grephead명령은 병렬로 시작합니다.
  • grep 입력을 읽고 처리를 시작합니다.
  • 어떤 시점에서 grep첫 번째 출력 덩어리를 생성합니다.
  • head 첫 번째 청크를 읽고 씁니다.
  • 처음 10 개 일치 이후에 충분한 행이 있다고 가정하면 (그렇지 않으면 grep먼저 종료 될 수 있음) 결국 head원하는 수의 행을 인쇄합니다. 이 시점에서 head종료합니다.
  • grephead프로세스 의 상대 속도에 따라 grep일부 데이터가 누적되어 아직 인쇄되지 않았을 수 있습니다. 시간에 head종료, grep입력을 읽거나이 계속 그렇게 할 것이다이 경우 내부 처리를 수행 할 수있다.
  • grep처리 된 데이터를 쓸 것입니다. 이 시점에서 SIGPIPE를 받고 죽습니다.

grep엄격하게 필요한 것보다 약간 더 많은 입력을 처리 할 가능성이 있지만 일반적으로 몇 킬로바이트에 불과합니다.

  • head일반적으로 몇 킬로바이트 단위로 읽습니다 ( read각 바이트에 대한 시스템 호출을 발행하는 것보다 효율적이기 때문에이 동작을 버퍼링이라고 함). 따라서 원하는 마지막 행 이후의 나머지 청크는 버려집니다.
  • 파이프에 커널이 관리하는 관련 버퍼 (대개 512 바이트)가 있으므로 전송중인 일부 데이터가있을 수 있습니다. 이 데이터는 폐기됩니다.
  • grep출력 청크가 될 준비가 된 일부 데이터를 축적했을 수 있습니다 (다시 버퍼링). 출력 버퍼를 비우려고 할 때 SIGPIPE를 수신합니다.

모든 시스템에서 필터링 유틸리티가 자연스럽게 효율적으로 작동하도록 정밀하게 설계되었습니다. 출력 채널이 종료 될 때 계속 진행해야하는 프로그램은 SIGPIPE 신호를 무시하는 단계를 수행해야합니다.


3

Sortof, 파이프 라인은 다음과 같이 작동합니다. 먼저 첫 번째 명령을 실행 한 다음 두 번째 명령을 실행합니다.

즉, A|B주어진 명령을 보자 . 그럼 여부 불확실 A하거나 B처음 시작합니다. CPU가 여러 개인 경우 정확히 동시에 시작할 수 있습니다. 파이프는 정의되지 않았지만 유한 한 양의 데이터를 보유 할 수 있습니다.

B가 파이프에서 읽으려고하지만 사용할 수있는 데이터가 없으면 데이터가 B도착할 때까지 기다립니다. B디스크에서 읽은 경우 B동일한 문제가 발생하여 디스크 읽기가 완료 될 때까지 기다려야합니다. 더 가까운 비유는 키보드를 읽는 것입니다. 이, B유형에 사용자를 기다릴 필요가있다. 그러나이 모든 경우에 B는 "읽기"작업을 시작했으며 완료 될 때까지 기다려야합니다. 그러나 B명령이 부분 출력 만 필요하면 입력 레벨에 도달 A한 특정 지점 이 SIGPIPE에 의해 종료됩니다.BA

경우 A시도가 파이프에 쓸 파이프가 가득, A무료가 될 파이프의 여지 기다려야합니다. A터미널에 쓰는 경우에도 같은 문제가 발생할 수 있습니다. 터미널에는 흐름 제어 기능이 있으며 데이터 속도를 조절할 수 있습니다. 어쨌든 to A는 "쓰기"작업을 시작했으며 쓰기 작업이 완료 될 때까지 기다립니다.

AB모든 공동 프로세스 파이프와 통신 할 것이지만, 동일 공정으로 행동한다. 어느 쪽도 다른 쪽을 완전히 통제 할 수 없습니다.


1
문제는 "B가 파이프의 측면을 닫을 때 A는 어떻게 할 것인가?"입니다.
enzotib

2
그것이 '파손 된 파이프'가 아닙니까?
Patkos Csaba

1
프로그램이 닫힌 파이프에서 읽기 / 쓰기를 시도하면 (예 : head종료) 프로그램에서 SIGPIPE 신호가 발생하고 기본 동작은 종료입니다.
Lekensteyn

이 질문에 정확히 어떻게 대답합니까? 보인다 psusi의 대답이 점에 더 짧고이다.
jw013

1

grep파이프를 직접 제어하지 않고 (데이터를 수신하는 중임) 파이프를 직접 제어하지 않고 grep(데이터를 보내고 있음) ...

어떤 grep다른 프로그램이하는, 또는, 전적으로 그 프로그램 내부 논리입니다. 당신이 말한다면 grep일찍 만들기 위해 명령 줄 옵션을 통해 발견 된 경우 출구 , 다음은, 그렇지 않으면에 건배 할 것이다 아주 패턴을 찾고 파일의 끝 ...

터미널은 내부 작동 grepshell배관 작업 과 상당히 분리되어 있습니다 ... 터미널은 기본적으로 런칭 패드이며 출력 디스플레이입니다 ...

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.