Linux에서 파일의 마지막 n바이트를 제외하고 모두 삭제하는 방법은 무엇입니까?

Linux에서 파일의 마지막 n바이트를 제외하고 모두 삭제하는 방법은 무엇입니까?

로그가 catalina.out.

다른 서버들은 너무 많은 공간을 차지하기 때문에 비자발적으로 중지되어야 했습니다. catalina.out적어도 서버를 삭제하고 다시 시작하는 것만으로 도 티켓에 대해 걱정할 필요가 없도록 접착 테이프로 이 문제를 고정하고 싶습니다 .

잘 모르겠지만 1일 로그가 5GB를 넘었습니다. 그럼, 내가 하고 싶은 일을 해보자예약 된 일들하루가 지난 파일이나 파일의 마지막 5GB를 삭제합니다. 여기서는 어떤 명령이 작동합니까?

이것이 문제에 대해 권장되는 솔루션입니까? 아니면 더 좋은 방법이 있나요?

답변1

catalina.out대부분이어야합니다비어 있는, 이는 애플리케이션이 모든 오류를 가로채서 자체적으로 처리하고 구성의 다른 곳에 기록할 수 있음을 의미합니다. 그러나 일반적으로 이는 완료되지 않고 catalina.out고려됩니다.이것응용 프로그램 로그. Tomcat은 기본적으로 파일을 회전하지 않기 때문에 문제가 발생합니다.

응용 프로그램을 복구하는 것 외에 파일을 자르는 더 좋은 방법 catalina.out은 특정 패키지 설치에서 이미 제공되거나(예: CentOS7용 tomcat 7에는 적절한 catalina.out로그 회전이 제공됨) 새로운 tomcat 버전을 사용하는 것입니다. ~처럼오류 64430WHO고정시키다최신 Tomcat에 통합되어 Tomcat >= 7.0.105, >= 8.5.56 및 >= 9.0.36으로 백포트되었습니다.

예(한 줄에 모두)

CATALINA_OUT_CMD="/usr/bin/rotatelogs -f $CATALINA_BASE/logs/catalina.out.%Y-%m-%d.log 86400"

회전된 파일을 추가로 처리해야 합니다.logrotate또는 이에 상응하는 특수 도구.

이제 이 질문에 대해 엄격하게 답하거나 최소한 단일 파일 처리에 관한 부분에 답하십시오 catalina.out. OP는 다음과 같이 썼습니다.

Linux에서 파일의 마지막 n바이트를 제외하고 모두 삭제하는 방법은 무엇입니까?

=> 끝을 유지

파일의 마지막 5GB를 삭제하세요.

=> 계속 시작하세요

계속 시작해

이로써 끝을 제거합니다. 삭제되더라도대신에 로그시작로깅은 나쁜 생각입니다.

POSIXtruncate(2):

이름

truncate - 파일을 지정된 길이로 자릅니다.

[...]

설명하다

truncate() 함수는 경로로 명명된 일반 파일의 크기를 length 바이트와 동일하게 만듭니다.

명령 구현이 있습니다 truncate(1). ~을 위한GNU 잘림(GNU 와 함께 stat(1))은 이와 같이 셸에서 사용됩니다(먼저 파일이 5GiB보다 큰지 확인해야 합니다. 그렇지 않으면 크기가 늘어납니다). 5GiB 예약:

if [ $(stat -c %s catalina.out) -gt $((5*1024*1024*1024)) ]; then
    truncate -s $((5*1024*1024*1024)) catalina.out
fi

결말을 지켜라

그러면 파일의 시작 부분이 삭제됩니다. 이는 다음을 사용하여 데이터 복사 없이 Linux 및 충분한 파일 시스템(예: Ext4, XFS...)에서 수행할 수 있습니다.fallocate(1)(추가 Linux 전용 기능 포함):

-p,--punch-hole

오프셋에서 시작하여 지속 길이 바이트까지 바이트 범위에서 공간을 확보합니다(즉, 구멍을 만듭니다).

여기에는 데이터 복사가 포함되지 않지만 블록 정렬(일반적으로 4096바이트 정렬)이 필요합니다. 복사 비용 없이 링 버퍼처럼 항상 파일 끝을 유지할 수 있습니다. 다음과 같이 사용할 수 있습니다(4096의 배수를 정렬하려면 추가 계산이 필요함).


oldsize=$(stat -c %s catalina.out) || exit 1

if [ $oldsize -gt $((5*1024*1024*1024)) ]; then
    holesize=$(( (oldsize-5*1024*1024*1024)/4096*4096 ))
    fallocate --punch-hole --length "$holesize" catalina.out
fi

--punch-hole--collapse-rangeTomcat의 진행 중인 출력이 중단되는 것을 방지하려면 (크기를 줄이기 위해 나머지 데이터를 처음으로 "이동") 대신 (파일을 희박하게 만들고 겉보기 크기를 유지하여 디스크 공간 확보)를 사용하십시오 catalina.out. 그렇지 않으면 Tomcat을 다시 시작 전후에 중지해야 합니다.

답변2

tail catalina.out > catalina.new
rm catalina.out
mv catalina.new catalina.out

그런 다음 tomcat을 다시 시작하거나 다시 로드하여 새 파일에 로그를 추가해야 합니다(현재는 삭제된 이전 catalina.out 파일에 대한 파일 설명자가 여전히 열려 있습니다).

tail(에서핵심 도구)에는 다음과 같은 매개변수가 있습니다.

-c, --bytes=[+]NUM마지막 바이트를 출력 하거나 NUM각 파일의 바이트부터 -c +NUM출력하는 데 사용됩니다.NUM

-n, 마지막 10줄 대신 --lines=[+]NUM마지막 몇 줄을 출력하거나 해당 줄로 시작하는 출력을 위해;NUM-n +NUMNUM

다른 매개변수에 대해서는 문의하십시오.man tail.

답변3

증상을 치료하는 대신 질병을 치료하십시오.

다른 사람들이 언급했듯이 "적절한 로깅"을 사용하면 이러한 문제를 피할 수 있습니다. 그러나 적절한 로깅에는 개발 팀, 개발-테스트-릴리스 주기 등이 포함됩니다. 문제를 해결하고 싶을 수도 있습니다.지금.

catalina.out패딩의 이유는 애플리케이션이 쓰기 stdout, 아마도 를 사용하거나 System.out.println유사하기 때문입니다. 이는 좋지 않으며 시간이 지남에 따라 수정되어야 합니다.

다행히 Tomcat에는 반창고가 있습니다. 당신이 해야 할 일은 META-INF/context.xml응용 프로그램(또는 <Context>정의가 있는 곳이면 어디든 아마도 conf/server.xml또는 conf/[engine]/[host]/[app].xml)에서 파일을 편집하고 다음을 추가하는 것뿐입니다 <Context>.

swallowOutput="true"

찾다https://tomcat.apache.org/tomcat-9.0-doc/config/context.html"swallowOutput"에 대해서는 지침을 참조하세요.

이렇게 하면 애플리케이션의 모든 내용을 가져와서 애플리케이션별 로그 파일에 저장합니다.회전 가능.

그러면 파일을 "단축"하는 게임을 하기보다는 며칠 후에 전체 로그 등을 삭제할 수 있습니다.

관련 정보