Raspberry Pi 3 Debian 최신 버전에서 다음 명령을 실행합니다.
cat /dev/ttyUSB0 | tee -a /media/pi/KINGSTON/klima.out | grep -F $ | tee -a /media/pi/KINGSTON/log
명령은 정상적으로 실행되고 예상대로 수행됩니다. 그러나 파일을 (수동으로 또는 CRON을 통해) 삭제하면 klima.out
다시 생성되지 않습니다. 명령은 계속 실행되고 로그 파일은 계속 추가되지만 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
시스템이 파일을 처리하는 방법을 이해하지 못합니다.
파일 항목을 삭제했지만 프로그램이 해당 핸들을 유지하는 한 파일은 계속 존재합니다. 따라서 티는 항목이 삭제되었다는 알림을 받지 못하며 여전히 파일에 씁니다.
하드 링크(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