다음 쉘 명령은 입력 스트림의 홀수 행만 인쇄해야합니다.
echo -e "aaa\nbbb\nccc\nddd\n" | (while true; do head -n 1; head -n 1 >/dev/null; done)
그러나 대신 첫 번째 줄을 인쇄합니다 aaa
.
-c
( --bytes
) 옵션 과 함께 사용하면 마찬가지입니다 .
echo 12345678901234567890 | (while true; do head -c 5; head -c 5 >/dev/null; done)
이 명령 1234512345
은 예상대로 출력 됩니다. 그러나 이것은 유틸리티 의 coreutils 구현 에서만 작동 head
합니다. 비지 박스의 출력이 단지 그래서 구현은 여전히 추가 문자를 먹는다 12345
.
이 특정 구현 방법은 최적화 목적으로 수행 된 것 같습니다. 줄이 끝나는 곳을 알 수 없으므로 읽을 문자 수를 알 수 없습니다. 입력 스트림에서 추가 문자를 사용하지 않는 유일한 방법은 스트림을 바이트 단위로 읽는 것입니다. 그러나 한 번에 한 바이트 씩 스트림에서 읽는 것이 느려질 수 있습니다. 따라서 head
입력 스트림을 충분히 큰 버퍼로 읽은 다음 해당 버퍼의 행을 계산합니다.
--bytes
옵션을 사용 하는 경우에도 마찬가지 입니다. 이 경우 읽을 바이트 수를 알고 있습니다. 따라서이 바이트 수만큼 정확하게 읽을 수 있습니다. corelibs의 구현은이 기회를 사용하지만, 비지 박스의 하나하지, 그것은 여전히 버퍼에 필요한 것보다 더 많은 바이트를 읽어 않습니다. 아마도 구현을 단순화하기 위해 수행되었을 것입니다.
그래서 질문입니다. head
유틸리티가 요청한 것보다 많은 문자를 입력 스트림에서 소비 하는 것이 맞 습니까? 유닉스 유틸리티에는 어떤 종류의 표준이 있습니까? 그리고 있다면,이 동작을 지정합니까?
추신
Ctrl+C
위의 명령을 중지하려면 을 눌러야 합니다. 유닉스 유틸리티는 그 이상을 읽는 데 실패하지 않습니다 EOF
. 누르기를 원하지 않으면 더 복잡한 명령을 사용할 수 있습니다.
echo 12345678901234567890 | (while true; do head -c 5; head -c 5 | [ `wc -c` -eq 0 ] && break >/dev/null; done)
나는 단순성을 위해 사용하지 않았다.