การล้างเนื้อหาของไฟล์ข้อความ


16

ฉันมีไฟล์ข้อความในโฮมไดเร็กตอรี่ของฉันซึ่งรับข้อมูลเป็นประจำผ่านงาน cron เนื่องจากงาน cron ให้ข้อมูลแบบไดนามิกฉันจึงต้องการตั้งค่างาน cron เพื่อล้างเนื้อหาไฟล์ (ไฟล์ยังคงมีอยู่) ฉันไม่ต้องการความช่วยเหลือ cron เพียงคำสั่งที่สามารถช่วยในการล้างไฟล์


5
ทางเลือก: tail -n +1000 file.txt > file.txtควรลบ 1,000 บรรทัดและเก็บบรรทัดใหม่ล่าสุดไว้ในไฟล์ (คุณไม่มีทางรู้ว่าคุณอาจต้องมีระเบียนล่าสุดเพื่อติดตามบางอย่าง)
Rinzwind

2
ที่จริงแล้วเป็นตัวเลือกที่ดีกว่าการล้างไฟล์ตามเวลาที่กำหนด
Bruno Pereira

1
@ Rinzwind ที่ใช้งานไม่ได้เนื่องจากไฟล์จะถูกตัดทอนก่อนที่หางจะพยายามอ่าน คุณต้องเปลี่ยนเส้นทางไปยังไฟล์ใหม่แล้วแทนที่ไฟล์เดิมด้วยไฟล์ใหม่
psusi

True @psusi :) ต้องมีการเปลี่ยนเส้นทางเพิ่มเติมที่นั่น
Rinzwind

คำตอบ:


28

วิธีที่ง่ายที่สุด:

> filename

นี่เป็นวิธีที่เห็นได้ชัดน้อยกว่าและอาจทำให้ผู้อื่นอ่านสคริปต์เชลล์ได้น้อยลง แต่ทุกอย่างที่คุณต้องการ

เนื่องจาก>ไม่ใช่คำสั่งจริง ๆ (เป็น bash builtin) คุณไม่สามารถใช้:

sudo > filename

เมื่อคุณไม่มีสิทธิ์ในไฟล์นั้น แต่คุณสามารถใช้:

sudo bash -c "> filename"

สิ่งที่ชนิดของสิทธิ์ที่จะต้องมีการเปลี่ยนแปลงเพราะมันบอกว่าอนุญาตปฏิเสธฉันได้ทำ chmod 755 ไปยังไฟล์ที่มีอยู่แล้วหรือฉันควรจะทำให้มันเป็นโพสต์ใหม่ (ผมหมายถึงคำถามสิทธิ์)
sosytee

@sosytee ดูการแก้ไขใหม่ของฉัน
Radu Rădeanu

1
@ sosytee แน่นอนคุณทำได้ แต่ใช้sudo crontab -eเพื่อเพิ่มงาน cron สำหรับรูทไม่ใช่สำหรับคุณ หรือเปลี่ยนสิทธิ์ในแฟ้มไป 766 (หรือ 666) ไม่ sudo chmod 766 filename755: เพิ่มเติมเกี่ยวกับ: codex.wordpress.org/Changing_File_Permissions
Radu Rădeanu

1
truncate filenameมีความสะอาดเป็นเล็ก ๆ น้อย ๆ sudoและง่ายกว่าเปลี่ยนเส้นทางออกที่ว่างเปล่าเพื่อไฟล์และไม่ได้ทำงานเป็นปัญหาที่มี
psusi

1
@psusi truncate -s 0 filenameแน่นอนสามารถทำให้เคล็ดลับ คุณสามารถเพิ่มมันเป็นคำตอบ
Radu Rădeanu

19

มีเครื่องมือที่สร้างขึ้นเพื่อวัตถุประสงค์ดังกล่าว:

truncate -s 0 filename

สิ่งนี้จะล้างเนื้อหา แต่จะยังคงเป็นไฟล์เดียวกัน ( inodeยังคงเหมือนเดิม)

สิ่งนี้มีความสำคัญเนื่องจากบางโปรแกรมมีตัวจัดการไฟล์ "โดย inode" สมมติว่าคุณ "ว่าง" ไฟล์โดยใช้วิธีการไร้เดียงสาของการลบและสร้างไฟล์ใหม่ บางโปรแกรมอาจจะยังคงถือจับไปยังแฟ้มเก่า (ที่มีเนื้อหาเก่า) lsแม้ว่าจะไม่สามารถมองเห็นวิธีการต่อตามปกติเช่น

ลิงก์บางอันไปยังรายละเอียดเพิ่มเติมในตอนท้ายของคำตอบนี้


วิธีอื่นอาจจำง่ายกว่า:

echo -n > filename

สิ่งนี้ยังคงไอโหนดเดียวกัน

โปรดทราบว่าทั้งสองtruncateและecho -nยังไม่ได้กำหนดโดยPOSIX

สำหรับ POSIX ให้ใช้cat /dev/null:

cat /dev/null > filename

อีกวิธีหนึ่งคลุมเครือมากขึ้นและอาจไม่ใช่ผู้ไม่เชื่อเรื่องพระเจ้า:

> filename

หากไฟล์ที่จะตัดทอนต้องมีสิทธิ์รูทในการเขียนดังนั้นบรรทัดต่อไปนี้จะไม่ทำงานอย่างที่คาดไว้:

sudo echo -n > filename
sudo cat /dev/null > filename
sudo > filename

นี่เป็นเพราะเชลล์ทำการเปลี่ยนเส้นทางโดยเชลล์ก่อนที่ sudo จะถูกเรียกใช้งาน นั่นหมายความว่าการเข้าถึงการเขียนไฟล์ทำได้โดยใช้สิทธิ์ของผู้ใช้ที่รันเชลล์ไม่ใช่สิทธิ์ที่จะได้รับจาก sudo

วิธีแก้ไขคือเลื่อนการเปลี่ยนเส้นทางไปยังเชลล์ที่ดำเนินการโดยใช้สิทธิ์ sudo ดังนี้:

sudo sh -c "echo -n > filename"

การใช้truncateคุณไม่จำเป็นต้องมีวิธีแก้ปัญหาเช่นนี้เนื่องจากเชลล์ไม่ได้ทำการเข้าถึงการเขียนโดยเชลล์truncateดำเนินการโดย sudo โดยใช้สิทธิ์ sudo

sudo truncate -s 0 filename

สำหรับรายละเอียดเต็มไปด้วยเลือดเกี่ยวกับโปรแกรมที่เปิดไฟล์ไว้แม้ว่าไฟล์นั้นจะถูกลบไปแล้วก็ตาม


มันบอกว่าอนุญาตปฏิเสธได้ใช้ชื่อไฟล์ chmod 755 แต่ยังคงได้รับอนุญาตถูกปฏิเสธ
sosytee

2
บางทีคุณเปิดใช้งาน noclobber ในทุบตี?
lesmana

คำตอบที่สมบูรณ์ที่สุดจนถึงตอนนี้
AbdelHady

4

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

ดูที่นี่เกี่ยวกับวิธีกำหนดค่า logrotate: http://linuxcommand.org/man_pages/logrotate8.html


1
ฉันชอบตัวเลือกนี้ด้วยตัวเอง เราใช้ "ไฟล์> 10 Mb" -> "tar.gz เพื่อสำรองข้อมูล" "ไฟล์เปล่า" และการสำรองข้อมูลจะถูกลบหลังจาก 900 วัน
Rinzwind

3

echo "" > foo_fileเป็นวิธีง่ายๆในการทำเช่นนั้นมันจะแทนที่เนื้อหาทั้งหมดของfoo_fileด้วย"" ซึ่งทำให้เป็นกรณีนี้ว่างเปล่า

นอกจากนี้คุณยังสามารถใช้cat /dev/null > foo_fileที่จะอ่านอุปกรณ์โมฆะและเขียนทับไฟล์ของคุณไม่มีอะไรเลย


มันบอกว่าอนุญาตปฏิเสธได้ใช้ชื่อไฟล์ chmod 755 แต่ยังคงได้รับอนุญาตถูกปฏิเสธ
sosytee

คุณสามารถอ่านการอนุญาตไฟล์กับผู้ใช้ปกติของคุณได้ไหม
Bruno Pereira

ใช่ฉันสามารถอ่านเนื้อหาตามปกติของผู้ใช้
sosytee
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.