Jak obciąć wszystkie pliki dziennika?


18

czy ktoś może mi dać rozwiązanie, aby obciąć cały plik dziennika w /var/log/katalogu?

i pytanie tylko o wiedzę, czy to dobry pomysł, czy nie?

#!/bin/bash
LOGDIR="/var/log"
for logfile in $(ls $LOGDIR/*log)
do
  truncate -s 0 $logfile
done

1
To NIE jest dobry pomysł - w /var/logtym miejscu system umieszcza wiadomości, których możesz potrzebować później. Ubuntu już wcześniej napotkał problem. Czytać man 8 logrotate;man logrotate.conf.
waltinator

Odpowiedzi:


34

Spróbuj tego:

truncate -s 0 /var/log/*log

EDYTOWAĆ:

jeśli chcesz to zrobić więcej niż jeden raz, powinieneś użyć logrotatedo obsługi dzienników. Zwykle jest instalowany w Ubuntu. Spójrz na man logrotate(lub jeśli nie masz go zainstalowanego, spójrz na stronę online lub zainstaluj go sudo apt-get install logrotate)

ze strony man:

Logrotate został zaprojektowany w celu ułatwienia administracji systemami, które generują dużą liczbę plików dziennika. Umożliwia automatyczne obracanie, kompresję, usuwanie i wysyłanie plików dziennika. Każdy plik dziennika może być przetwarzany codziennie, co tydzień, co miesiąc lub gdy staje się zbyt duży.


możesz też je opróżnić za pomocą echa „”> * log
Astm

10

Jeśli chcesz wyczyścić wszystkie pliki dziennika, nie tylko te z folderu dziennika pierwszego poziomu, możesz użyć:

shopt -s globstar                  # if needed
truncate -s 0 /var/log/*.log       # first-level logs
truncate -s 0 /var/log/**/*.log    # nested folders, like /var/log/nginx/access.log

Zauważ, że jeśli już masz logrotateuruchomiony, musisz również wyczyścić obrócone .gzdzienniki:

find /var/log -type f -name '*.[0-99].gz' -exec rm {} +

Prawidłowym zastosowaniem tego może być na przykład zbudowanie kontenera urządzenia VM do dystrybucji.

Należy nie trzeba zrobić to jako część rutynowej konserwacji: DEM jak słusznie zaproponował wykorzystanie logrotatedo tego.


1

W odpowiedzi na odpowiedź @DEN

Spowoduje to znalezienie wszystkich plików dziennika /var/logi obcięcie ich do 0 bajtów.

find /var/log -type f -iname '*.log' -print0 | xargs -0 truncate -s0

1
Użyłbym *.log*zamiast tego, ale nie jestem pewien, czy jest w 100% bezpieczny, więc nie uwzględniłem tego w odpowiedzi. Ponieważ istnieją pliki takie jak dovecot.log-20180930i dovecot.log-20180923.gz.
Luka,

0

Istnieje kilka metod pełnego obcięcia pliku, ogólnie stosowanych w większości systemów operacyjnych zgodnych z POSIX. Najczęściej spotykane w skryptach powłoki jest coś w rodzaju true > file.txtlub : > file.txt(w przypadku bashpowłoki >wystarczające jest samo przekierowanie). Wynika to ze sposobu, w jaki >otwiera się pliki przez open()lub openat()syscall z O_WRONLY|O_CREAT|O_TRUNCflagami - czyta tylko do zapisu LUB tworzy, jeśli nazwa pliku nie istnieje, LUB obcina istniejącą nazwę pliku.

Mając to na uwadze, sami możemy zaimplementować coś takiego:

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc, char **argv){
    if (argc == 2){
        int fd = open(argv[1],O_TRUNC);
        close(fd);
    }

    return 0;
}

Nazwij plik, który przechowuje ten kod jako, trunc.ci skompiluj go gcc trunc.c -o trunc, a będziesz mieć małe narzędzie, które obetnie argument nazwy pliku podany tak jak w trunc ./foobar.txt. Oczywiście ten kod nie wykonuje innych kontroli, tylko obcina pierwszy parametr pozycyjny. Pozostawiam czytelnikom ustalenie, jak radzić sobie z więcej niż jednym parametrem pozycyjnym. Na marginesie, istnieje także truncate()syscall, którego moglibyśmy użyć i skrócić plik do zmiennej długości.

Teraz, jeśli nie jesteś fanem C, Python może być dla Ciebie łatwiejszy. open()polecenie działa na tej samej zasadzie w Pythonie - otwieranie pliku do zapisu i obcinanie, jeśli nazwa pliku istnieje. W ten sposób możemy zrobić

python -c 'import sys;open(sys.argv[1],"w").close()' passwd.copy 

Jeśli chodzi o znajdowanie wszystkich .logplików, zostało to już omówione w innych odpowiedziach - użyj *glob lub rozszerzonego glob w bash. Jest też find -type f -name "*.log", który ma -execflagę do uruchamiania poleceń (w tym konkretnym przypadku, sh -c ''aby skorzystać, >ponieważ >jest operatorem powłoki, a nie zewnętrznym plikiem wykonywalnym). W ten sposób możesz zrobić

find /var/log -type f -name "*.log" -exec sh -c 'true > "$1"' sh {} \;

Warto również zauważyć, że pliki dziennika w katalogu, takie jak /var/logczęsto są obracane przez logrotate usługi, więc nie będzie takie jak nazwy plików /var/log/service.log, /var/log/service.log.1itp, więc może chcesz użyć *.log.[1-9]wzoru zamiast


Między innymi możemy skopiować /dev/nulldo żądanego pliku. Co dziwne, mimo że /dev/nulljest to plik typu specjalnego urządzenia, gdy kopiujesz go w innym miejscu, wynikiem jest pusty zwykły plik, przynajmniej w GNU cp. W ten sposób możemy zrobić

cp /dev/null foo.txt

lub

dd if=/dev/null of=foo.txt

Inne sugerowane lektury:


0

Dobrą praktyką jest obracanie dzienników w / var / logs w celu obracania za pomocą funkcji logrotate, ale nie zawsze, gdy chcemy. Dzienniki systemowe zostaną wydrukowane i będą przydatne do debugowania ewentualnych awarii.

Jeśli wymagane jest nie używanie logrotate, można zbadać opcje. Chociaż obcinanie jest łatwą opcją w kilku odmianach systemu uniksowego, to polecenie nie jest łatwo dostępne, należy je zainstalować. Jeśli nie można zainstalować nowego polecenia, można użyć poniższej pętli.

for logfile $(ls /path/*.log)
do 
  cat /dev/null > $logfile
done

Bash Pitfall # 1 : Nie pisz w ten sposób dla pętli. Użyj for logfile in /path/*.logzamiast tego.
PerlDuck
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.