파이프의 마지막 N 바이트만 유지하시겠습니까?

파이프의 마지막 N 바이트만 유지하시겠습니까?

소켓에서 파일로 데이터를 전송하고 있습니다. 모든 데이터를 저장해야 한다면 다음과 같이 간단합니다.

$ nc -l 5001 > file.bin

첫 번째 바이트만 저장하고 싶다면 n다음과 같습니다.충분히 쉬움게다가:

$ nc -l 5001 | pv -Ss 2M > file.bin

새 데이터가 도착하면 큐처럼 파일의 이전 데이터를 대체할 수 있도록 최대 크기가 고정된 파일로 데이터를 파이프하는 방법이 있습니까? 그런 것이 존재한다면 고정 크기의 명명된 파이프를 사용할 수도 있습니다.

이상적으로는 모든 파일을 저장한 다음 잘라낼 필요 없이 지속적으로 실행됩니다. 즉, tail단순히 파일 전체를 저장한 후 실행하고 싶지는 않습니다.

답변1

n = 2M인 경우 다음을 사용합니다.

nc -l 5001 | tail -c 2M > file.bin

또는 다음을 사용하세요.

nc -l 5001 | tail -c 2097152 > file.bin

답변2

따라서 더 많은 바이트를 저장하지 않고도 언제든지 마지막 N 바이트를 볼 수 있기를 원합니다. 제가 올바르게 이해하고 있습니까?

이 작업을 실시간으로(바이트 단위로) 수행하려면 아마도 특수 소프트웨어가 필요할 것입니다. 일반적으로 사람들은 링 버퍼에 최신 데이터를 저장하지만, 파일에서 이렇게 배열된 데이터를 읽을 수 있는 소프트웨어는 찾을 수 없습니다. 또 다른 옵션은 모든 데이터를 일반적인 방법으로 파일에 쓰고 더 이상 필요하지 않은 오래된 데이터를 삭제하도록 운영 체제에 주기적으로 지시하는 것입니다. (이전에 이 내용을 제안하는 댓글을 본 것 같은데 삭제된 것 같습니다.)

아마도 Perl 스크립트를 사용하여 이 작업을 수행할 수 있습니다.fallocate버리다.

최신 데이터가 필요하지 않은 경우 빠르고 더러운 쉘 솔루션은 고정 블록을 파일에 저장하고 각 블록 사이에서 파일 이름을 다른 이름으로 바꾸는 것입니다. 최신 전체 블록은 항상 두 번째 파일에서 사용할 수 있습니다.

예를 들어

i=0
while true; do echo $i; sleep .1; i=$((i+1)); done |
    while true; do
        head -10 > out1
        mv out1 out2
    done

첫 번째 루프는 몇 가지 테스트 출력을 생성하는 반면, 두 번째 루프는 10개 라인의 블록을 읽어 마지막 전체 블록이 에 들어가고 out2마지막 부분 블록이 에 들어가도록 합니다 out1. head필요에 따라 매개변수를 변경합니다.

이러한 작은 청크의 경우 출력 버퍼는 항상 비어 있는 head것으로 out1나타납니다. stdbuf -o0 head ...이것이 문제라면 사용하세요.

관련 정보