tee -a는 파일을 다시 생성하지 않습니다.

tee -a는 파일을 다시 생성하지 않습니다.

Raspberry Pi 3 Debian 최신 릴리스에서 다음 명령을 실행하고 있습니다.

cat /dev/ttyUSB0 | tee -a /media/pi/KINGSTON/klima.out | grep -F $ | tee -a /media/pi/KINGSTON/log

명령은 제대로 작동하며 해야 할 일을 수행합니다. 그러나 klima.out파일을 삭제(수동 또는 CRON으로)하면 다시 생성되지 않습니다. 명령이 계속 실행되고 로그 파일이 계속 추가되지만 파일 klima.out이 다시 표시되지 않습니다. (버퍼링도 없음) 모든 경계를 넘어서 자라지 못하게 일주일에 한 번씩 삭제하고 싶습니다. 어떤 제안이 있으십니까?

답변1

귀하의 파이프라인이 오랫동안 실행되고 있으며 실행 중에 로그 파일을 제거하려고 한다고 가정합니다.

파일을 삭제해도 tee프로세스는 쓰기 위해 파일을 계속 열어 두는데, 이는 디스크 공간이 시스템에 다시 반환되지 않음을 의미합니다. 파일을 참조하는 열려 있는 모든 파일 설명자가 닫힐 때까지는 이런 일이 발생하지 않습니다.

삭제 전에 파일 설명자가 할당되어 있는 한 삭제된 파일에 쓰는 것은 전혀 문제가 없습니다.

파일을 다시 생성하고 이전(현재 이름 없음) 로그 파일이 차지한 공간을 회수하려면 파이프라인을 다시 시작해야 합니다.

파이프라인을 다시 시작하지 않으려면 다음을 선택할 수 있습니다.잘리다즉, 파일을 제거하지 않고 크기를 0으로 줄입니다. 이렇게 하면 tee파일을 다시 열지 않고도 파일에 계속 추가할 수 있습니다.

파일 자르기가 수행될 수 있습니다.jlliagre가 그의 답변에서 보여준 것처럼truncate, 또는 (GNU coreutils의 일부인 비표준 유틸리티)을 사용하여 :

truncate -s 0 /media/pi/KINGSTON/klima.out

보다매뉴얼truncate해당 유틸리티에 대한 자세한 내용을 보려면

답변2

파일 블록을 복구하려면 링크를 해제하지 말고 파일을 비워야 합니다.

이 이식 가능한 방법은 대부분의 쉘에서 작동합니다.

: > /media/pi/KINGSTON/klima.out

파일 링크 해제(예: rm)는 디렉토리 항목을 제거하지만 판독기 또는 작성자가 파일을 열어 두는 한 파일 내용(inode)에는 영향을 주지 않습니다.

답변3

시스템이 파일을 처리하는 방법을 이해하지 못합니다.

파일 항목을 삭제했지만 프로그램이 파일에 대한 핸들을 유지하는 한 파일은 계속 존재합니다. 따라서 tee에는 항목이 삭제되었다는 알림이 전송되지 않으며 여전히 파일에 기록됩니다!

고유한 파일에는 하드 링크(ln 명령으로 생성됨) 덕분에 많은 항목이 있을 수 있습니다.

파일에 쓰는 모든 줄에서 파일을 닫고 여는 자신만의 tee 버전을 작성할 수 있지만 너무 많은 시스템 호출을 생성하므로 성능이 매우 저하됩니다.

다음은 입력을 여러 파일로 분할하는 쉘 함수입니다.

splitSizeInKio=100

splitInput(){
    local PS4='+splitInput+ '
    set -x
    local i=0
    local fname="$1"
    local ii

    while true
    do if [ $i -lt 10 ]
       then ii=0$i
       else ii=$i
       fi
       local outfile="$fname".$ii
       dd of="$outfile" bs=1024 count=$splitSizeInKio
       i=$((i+1))
    done
}

(크기 대신 여러 줄에 쏟은 경우 "dd" 대신 "head"를 사용할 수 있습니다.)

Bash를 사용하면 다음과 같이 "프로세스 대체"를 사용할 수 있습니다.

prog1 | tee >( splitInput somefilename ) | prog2

관련 정보