Як усікати всі логіни?


18

хтось може дати мені рішення для врізання всіх журналів файлів у /var/log/каталозі?

і питання лише для знань, це гарна ідея чи ні?

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

1
Це НЕ гарна ідея - /var/logде система ставить повідомлення, які вам можуть знадобитися пізніше. Ubuntu раніше стикався з проблемою. Прочитайте man 8 logrotate;man logrotate.conf.
waltinator

Відповіді:


34

спробуйте це:

truncate -s 0 /var/log/*log

Редагувати:

якщо ви хочете робити це не раз, вам слід використовувати logrotateдля обробки своїх журналів. Зазвичай він встановлюється в ubuntu. Подивіться man logrotate(або якщо у вас його не встановлено, подивіться на онлайн-сторінку або встановіть її sudo apt-get install logrotate)

з сторінки сторінки:

logrotate призначений для полегшення адміністрування систем, які генерують велику кількість файлів журналів. Це дозволяє автоматично обертати, стискати, видаляти та відправляти файли журналів. Кожен файл журналу може оброблятися щодня, щотижня, щомісяця або коли він занадто великий.


також ви можете їх спорожнити за допомогою журналу echo ""> *
Astm

10

Якщо ви хочете очистити всі файли журналів, а не лише файли журналу першого рівня, ви можете використовувати:

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

Зауваживши, що якщо у вас вже logrotateзапущені, вам також потрібно очистити поворотні .gzжурнали:

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

Допустимим використанням для цього може бути, наприклад, побудова контейнера пристрою VM для розповсюдження.

Вам не потрібно робити це в рамках звичайного технічного обслуговування: як цілком коректно запропоновано DEM, використовуйте logrotateдля цього.


1

Як відповісти до відповіді @DEN

Тут ви знайдете всі файли журналів /var/logі обріжте їх до 0 байт.

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

1
Я б *.log*замість цього використовував, але не впевнений, що це на 100% безпечно, тому я не включив його у відповідь. Тому що є файли як dovecot.log-20180930і dovecot.log-20180923.gz.
Лука

0

Існує кілька методів повного обрізання файлу, загальноприйнятних для більшості ОС, сумісних з POSIX. Найбільш поширене, що ви побачите при сценаріїх оболонок - це щось на зразок true > file.txtабо : > file.txt(а у випадку bashоболонки >достатньо лише перенаправлення). Це пов’язано з тим, як >відкриваються файли через open()або openat()syscall за допомогою O_WRONLY|O_CREAT|O_TRUNCпрапорів - що читає лише для запису АБО створювати, якщо ім'я файлу не існує, АБО усікає існуюче ім’я файлу.

Зважаючи на це, ми можемо реалізувати щось подібне в C:

#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;
}

Назвіть файл, у якому зберігається цей код, trunc.cі скомпілюйте його gcc trunc.c -o trunc, і у вас є невелика утиліта, яка вріже аргумент імені файлу, який він надає як у trunc ./foobar.txt. Звичайно, цей код не робить інших перевірок, він лише скорочує перший позиційний параметр. Я залишлю це для читачів, щоб зрозуміти, як поводитися з більш ніж одним позиційним параметром. Зі сторони, є truncate()syscall, який ми могли б також використовувати, і врізати файл до змінної довжини.

Тепер, якщо ви не шанувальник C, Python може бути простішим для вас. open()команда працює за тим же принципом у Python - відкриття файлу для запису та обрізання, якщо ім'я файлу існує. Таким чином ми можемо зробити

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

Щодо пошуку всіх .logфайлів, про це вже йшлося в інших відповідях - використовуйте *глобул або розширений глобус у bash. Там же find -type f -name "*.log"є -execпрапор для запуску команд (у цьому конкретному випадку, sh -c ''щоб скористатися, >тому що >це оператор оболонки, а не зовнішній виконуваний файл). Таким чином ви можете зробити

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

Варто також зазначити, що файли журналів у каталозі, наприклад, /var/logчасто обертаються службою logrotate, тому будуть імена файлів, такі як /var/log/service.log, /var/log/service.log.1і т. Д., Тож ви можете використовувати *.log.[1-9]замість цього шаблон


Крім усього іншого, ми можемо скопіювати /dev/nullу потрібний файл. Як не дивно, навіть якщо /dev/nullце файл спеціального символьного типу файлу, коли ви копіюєте, що в іншому місці результат порожній звичайний файл, принаймні, з GNU cp. Таким чином ми можемо зробити

cp /dev/null foo.txt

або

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

Інші запропоновані читання:


0

Добре практично обертати журнали в / var / logs, щоб обертатися з функцією logrotate, але не коли б ми хотіли. Системні журнали будуть надруковані на ній, і вони будуть зручні для налагодження будь-яких збоїв.

Якщо це вимога не використовувати логротат, то варіанти можна вивчити. Хоча усікати є простим варіантом у кількох варіантах системи Unix, ця команда недоступна легко, її потрібно встановити. Якщо заборонено встановлювати нову команду, тоді можна використовувати нижче циклу.

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

Bash Pitfall №1 : Таким чином не пишіть для циклів. Використовуйте for logfile in /path/*.logзамість цього.
PerlDuck
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.