Skrypt, który napisałem, coś robi, a na końcu dołącza kilka wierszy do własnego pliku dziennika. Chciałbym zachować tylko ostatnie n linii (powiedzmy 1000 linii) pliku dziennika. Można to zrobić na końcu skryptu w następujący sposób:
tail -n 1000 myscript.log > myscript.log.tmp
mv -f myscript.log.tmp myscript.log
ale czy istnieje bardziej czyste i eleganckie rozwiązanie? Być może dokonano tego za pomocą jednego polecenia?
text-processing
tail
logs
dr01
źródło
źródło
logrotate
to eleganckie rozwiązanieOdpowiedzi:
Jest to możliwe, ale jak powiedzieli inni, najbezpieczniejszą opcją jest wygenerowanie nowego pliku, a następnie przeniesienie tego pliku w celu zastąpienia oryginału.
Poniższa metoda ładuje wiersze do BASH, więc w zależności od liczby wierszy
tail
, wpłynie to na użycie pamięci przez lokalną powłokę do przechowywania zawartości wierszy dziennika.Poniżej usuwa również puste wiersze, jeśli istnieją na końcu pliku dziennika (z powodu zachowania oceny BASH
"$(tail -1000 test.log)"
), więc nie zapewnia naprawdę 100% dokładnego obcięcia we wszystkich scenariuszach, ale w zależności od sytuacji może być wystarczające.źródło
Narzędzie
sponge
jest przeznaczone tylko do tego przypadku. Jeśli masz go zainstalowanego, możesz napisać dwa wiersze:Zwykle czytanie z pliku w tym samym czasie, w którym piszesz do niego, jest zawodne.
sponge
rozwiązuje to, nie pisząc do,myscript.log
dopókitail
nie skończy czytać i zakończy potoku.zainstalować
Aby zainstalować
sponge
w systemie podobnym do Debiana:Aby zainstalować
sponge
w systemie RHEL / CentOS, dodaj repozytorium EPEL, a następnie:Dokumentacja
Od
man sponge
:źródło
sponge
. Bardzo przydatny dla wszystkich, którzy nauczyli się trudnej drogi, której nie da się zrobićsort importantfile.txt > importantfile.txt
:)zdecydowanie „tail + mv” jest znacznie lepszy! Ale dla gnu sed możemy spróbować
źródło
Dla przypomnienia,
ed
możesz zrobić coś takiegoOtworzy się
infile
ir
zablokuje na wyjściutail -n 1000 infile
(tj. Wstawi to wyjście przed 1. linią), a następnie usunie z tego, co początkowo było 1. linią do końca pliku. Wymienić,p
zw
edytować plik w miejscu.Pamiętaj jednak, że
ed
rozwiązania nie są odpowiednie dla dużych plików.źródło
W skrypcie możesz zastosować logikę rotacji logów. Wykonaj wszystkie logowanie za pomocą funkcji:
Ta funkcja po pierwsze działa w następujący sposób:
następnie sprawdza rozmiar pliku lub w jakiś sposób decyduje, że plik wymaga rotacji. W tym momencie plik
logfile.1
, jeśli istnieje, jest usuwany, pliklogfile.0
, jeśli istnieje, zostaje przemianowany nalogfile.1
ilogfile
zostaje przemianowany nalogfile.0
.Decyzja, czy obrócić, może być oparta na liczniku utrzymywanym w samym skrypcie. Gdy osiągnie 1000, jest resetowane do zera.
Jeśli wymagane jest zawsze ścisłe przycięcie do 1000 wierszy, skrypt może zliczyć liczbę wierszy w pliku dziennika podczas uruchamiania i odpowiednio zainicjować licznik (lub jeśli liczba już osiąga lub przekracza 1000, wykonaj obrót natychmiast).
Lub możesz uzyskać rozmiar, na przykład za pomocą
wc -c logfile
i wykonaj obrót w oparciu o przekroczenie określonego rozmiaru. W ten sposób plik nigdy nie musi być skanowany w celu ustalenia warunku.źródło
Zrobiłem użycie zamiast
mv
Thecp
polecenie, aby osiągnąć to, że jesteś w stanie mieć jakieś logi prawo w miejscu, w którym program jest uruchomiony. Może w innym katalogu użytkownika domowego lub w katalogu aplikacji i mieć wszystkie dzienniki w jednym miejscu jako linki dowiązane. Jeśli użyjeszmv
polecenia, utracisz twardy link. Jeślicp
zamiast tego użyjesz polecenia, zachowasz ten twardy link.mój kod jest jak:
Więc jeśli pliki znajdują się w tym samym systemie plików, możesz również dać użytkownikom różne prawa i
${LOGFILE_DIR}
modyfikować długość tak jak ja.Jeśli jest to
mv
polecenie, tracisz dowiązanie twarde między plikami, więc twój drugi plik nie jest bardziej połączony z pierwszym - być może umieścił gdzieś indziej.Jeśli w innym miejscu nie pozwalasz komuś na usunięcie pliku, twoje dzienniki pozostają razem i są dobrze kontrolowane za pomocą własnego skryptu.
logrotate
może milszy. Ale cieszę się z tego rozwiązania.Nie przejmuj się „”, ale w moim przypadku są jakieś pliki ze spacjami i innymi specjalnymi literami, a jeśli nie wykonam „” lub {}, cała partia nie będzie ładna.
Na przykład istnieje katalog, w którym starsze pliki są automatycznie spakowane do pliku,
OLDFILE.zip
a wszystko, co jest spakowane, jest również wymienione w pliku,.zip_log
więc.zip_log
jest również w tym katalogu, ale wLOGFILE_DIR
Mam:równy plik, ponieważ jest to twardy link.
źródło