จะตัดทอนไฟล์บันทึกทั้งหมดได้อย่างไร?


18

ใครสามารถให้ฉันวิธีการตัดทอน logfile ทั้งหมดใน/var/log/ไดเรกทอรี?

และคำถามสำหรับความรู้มันเป็นความคิดที่ดีหรือไม่?

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

1
ไม่ใช่ความคิดที่ดี - /var/logเป็นที่ที่ระบบจะส่งข้อความที่คุณอาจต้องการในภายหลัง อูบุนตูเคยพบปัญหามาก่อน man 8 logrotate;man logrotate.confอ่าน
waltinator

คำตอบ:


34

ลองนี้:

truncate -s 0 /var/log/*log

แก้ไข:

หากคุณต้องการทำมากกว่าหนึ่งครั้งคุณควรใช้logrotateเพื่อจัดการบันทึกของคุณ โดยปกติจะติดตั้งใน Ubuntu ดูที่man logrotate(หรือถ้าคุณไม่ได้ติดตั้งดูที่manpage ออนไลน์หรือติดตั้งด้วยsudo apt-get install logrotate)

จาก manpage:

logrotate ถูกออกแบบมาเพื่อให้ง่ายต่อการดูแลระบบที่สร้างไฟล์บันทึกจำนวนมาก จะช่วยให้การหมุนอัตโนมัติการบีบอัดการลบและการส่งไฟล์บันทึกทางไปรษณีย์ ไฟล์บันทึกแต่ละไฟล์อาจได้รับการจัดการรายวันรายสัปดาห์รายเดือนหรือเมื่อไฟล์มีขนาดใหญ่เกินไป


นอกจากนี้คุณสามารถล้างพวกเขาโดยใช้ echo ""> * log
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
Luka

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ไฟล์ที่ได้รับการกล่าวถึงในคำตอบอื่น ๆ แล้ว - ใช้*glob หรือ glob 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เป็นประเภทอุปกรณ์อักขระพิเศษของไฟล์เมื่อคุณคัดลอกที่อื่น ๆ ผลที่ได้คือที่ว่างเปล่าแฟ้มปกติอย่างน้อยกับ cpGNU ดังนั้นเราสามารถทำได้

cp /dev/null foo.txt

หรือ

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

การอ่านที่แนะนำอื่น ๆ :


0

มันเป็นการดีที่จะหมุนบันทึกใน / var / logs เพื่อหมุนด้วยฟังก์ชั่น logrotate แต่ไม่ใช่ทุกครั้งที่เราต้องการจะทำ บันทึกของระบบจะถูกพิมพ์ออกมาและจะเป็นประโยชน์ในการแก้ไขข้อผิดพลาดใด ๆ

หากเป็นข้อกำหนดที่จะไม่ใช้ logrotate จะสามารถสำรวจตัวเลือกได้ แม้ว่าการตัดทอนเป็นตัวเลือกที่ง่ายในระบบ unix ที่รสชาติไม่กี่คำสั่งนี้ไม่พร้อมใช้งาน แต่จำเป็นต้องติดตั้งหากไม่ได้รับอนุญาตให้ติดตั้งคำสั่งใหม่คุณสามารถใช้ลูปด้านล่างได้

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

Bash Pitfall # 1 : อย่าเขียนว่าเป็นลูป ใช้for logfile in /path/*.logแทน
PerlDuck
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.