เกิดอะไรขึ้นกับสคริปต์ทุบตีของฉันเพื่อเก็บไฟล์ x ล่าสุดและลบส่วนที่เหลือ


7

ฉันมีสคริปต์ทุบตีนี้ซึ่งสำรองฐานข้อมูลของฉันในกำหนดการ cron:

#!/bin/sh

PT_MYSQLDUMPPATH=/usr/bin
PT_HOMEPATH=/home/philosop
PT_TOOLPATH=$PT_HOMEPATH/philosophy-tools
PT_MYSQLBACKUPPATH=$PT_TOOLPATH/mysql-backups
PT_MYSQLUSER=*********
PT_MYSQLPASSWORD="********"
PT_MYSQLDATABASE=*********
PT_BACKUPDATETIME=`date +%s`
PT_BACKUPFILENAME=mysqlbackup_$PT_BACKUPDATETIME.sql.gz
PT_FILESTOKEEP=14

$PT_MYSQLDUMPPATH/mysqldump -u$PT_MYSQLUSER -p$PT_MYSQLPASSWORD --opt $PT_MYSQLDATABASE | gzip -c > $PT_MYSQLBACKUPPATH/$PT_BACKUPFILENAME

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

ทุกคนสามารถช่วยฉันด้วยส่วนที่เหลือของสคริปต์ BASH เพื่อเพิ่มการล้างไฟล์? ความรู้เรื่องการทุบตีของฉันขาดไปและฉันไม่สามารถแยกรหัสเพื่อทำส่วนที่เหลือ

คำตอบ:


9

ก่อนอื่นให้แน่ใจว่าคุณอยู่ในโฟลเดอร์ที่ถูกต้อง:

if [ -z $PT_MYSQLBACKUPPATH ]; then
 echo "No PT_MYSQLBACKUPPATH set. Exit"
 exit 1
fi
cd $PT_MYSQLBACKUPPATH
if [ $? != 0 ]; then
 echo "cd to PT_MYSQLBACKUPPATH failed. Exit"
 exit 1
fi

คุณสามารถลบไฟล์ที่เก่ากว่า n ในกรณีของคุณ:

find -mtime +14 -delete

ลบไฟล์ที่เก่ากว่า 14 วัน

วิธีแก้ปัญหาที่ซับซ้อนกว่านี้ (ไม่ใช่วิธีที่เหมาะสมที่สุด) สำหรับคำถามของคุณ:

# Get list of newest files. If newest files are first, use head -n 14 instead of 
# head.
files=(`ls | sort | tail -n 14`)
# Loop over all files in this folder
for i in *; do 
 preserve=0; 
 #Check whether this file is in files array:
 for a in ${files[@]}; do 
  if [ $i == $a ]; then 
   preserve=1; 
  fi; 
 done; 
 # If it wasn't, delete it (or in this case, print filename)
 if [ $preserve == 0 ]; then 
  echo $i; # test first, then change this to "rm $i"
 fi;
done

นี่ไม่ใช่สิ่งที่ฉันเป็นจริงหลังจากนั้น แต่จริง ๆ แล้วจะทำงานได้ดีกว่าที่ฉันคิดไว้ ก่อนที่ฉันจะทดสอบฉันจะแน่ใจได้อย่างไรว่านี่คือการทำงานใน PT_MYSQLBACKUPPATH ไม่ต้องการเรียกใช้สิ่งนี้นอกเหนือจากนั้นมิฉะนั้นจบลงด้วยการลบไฟล์ทั้งหมด อาจเป็นหายนะ ...
Brady

@Brady: ฉันได้เพิ่มตัวอย่างสำหรับการตรวจสอบสภาพแวดล้อม
Olli

2
อย่า เคย ใช้ for i in $(ls) หรือ var=($(ls)) (คำแนะนำ: for i in * ) เว้นแต่คุณจะมั่นใจได้ 400% ว่าชื่อไฟล์จะไม่มีช่องว่างหรืออะไรทำนองนั้น
grawity

@Olli - ตกลงว่าสคริปต์ทำงานในขณะนี้โดยไม่มีข้อผิดพลาด แต่ฉันจะไม่สามารถบอกได้ว่าการลบ 14 วันทำงานได้หรือไม่จนกว่าฉันจะมีไฟล์เก่าอยู่ในนั้น จะกลับมาเยี่ยมชมอีกครั้งใน 14 วันหากมีปัญหา ขอบคุณสำหรับความช่วยเหลือ
Brady

1
ls | sort เรียงลำดับตาม ชื่อ . ใช้ ls -t | head -n 14 (มันจะยังคงล้มเหลวสำหรับชื่อไฟล์ที่มีช่องว่าง)
Dennis Williamson

11

คุณสามารถลองอันนี้:

ls -r1 $PT_MYSQLBACKUPPATH/ | tail -n +$(($PT_FILESTOKEEP+1)) | xargs rm

ls -r1 จะแสดงรายการไฟล์ทั้งหมดในลำดับย้อนกลับหนึ่งไฟล์ต่อบรรทัด

tail -n +$number กรองไฟล์ $ number-1 แรกของรายการออก (resp. แสดงไฟล์ทั้งหมดที่เริ่มต้นจาก $ number จนถึงไฟล์สุดท้าย)

xargs จะดำเนินการ rm พร้อมชื่อไฟล์ทั้งหมดจากอินพุตมาตรฐาน


ขอบคุณสำหรับคำตอบของคุณ bmk แต่ฉันได้ไปกับการใช้ค้นหา -mtime +14 -delete จัดหาโดย Olli
Brady

+1 เพราะนี่ตอบคำถามได้อย่างแม่นยำมาก
DevSolar

3

นี่คือการใช้แรงบันดาลใจของฉันจากโพสต์นี้:

#!/bin/bash
# Thu Jun 28 13:22:53 CEST 2012
# ${DESTDIR}/files2keep.sh
# Keep the 3 yungest files
# mra at miracleas.dk , deployed on RHEL 6.
InitValues(){
TODAY=`date +"%Y%m%d"`
NOW=`date +"%H%M"`
DESTDIR=/mnt/dbdmp
LOGFILE=?{0}-${TODAY}-${NOW}.log
}
BackupFileMaintenance(){
KEEPFILES=(`ls -lrt ${DESTDIR}/*mysqldump.sql.gz| tail -n 3| awk '{print $9}'`)
    for i in `ls -lrt ${DESTDIR}/*mysqldump.sql.gz | awk '{print $9}'`; do
    preserve=0 
    #Check whether this file is in files array:
        for a in ${KEEPFILES[@]}; do
                if [ $i == $a ]; then
                preserve=1 
                fi 
        done 
    if [ $preserve == 0 ]; then
    echo $i; # then change this to "rm -f $i" after test
    fi
    done
}
InitValues
BackupFileMaintenance
exit

3

เกี่ยวกับคำตอบจาก bmk เมื่อพร้อมใช้งาน ls -t1 ปลอดภัยกว่า -r1 (จัดเรียงตามเวลาในการปรับเปลี่ยนมากกว่าลำดับไฟล์โดยพลการ)

นอกจากนี้ในบางรุ่นของไวยากรณ์หางก็คือ tail -n +$number (ตัวเลือก - จำเป็นต้องมี)

เป็นโบนัสที่รวมทั้งการค้นหาและ ls นี่คือวิธีลบไฟล์ที่เก่ากว่า 30 วัน แต่เก็บไว้อย่างน้อย 15 ไฟล์:

ls -t1 $PT_MYSQLBACKUPPATH/|tail -n +16| xargs -n1 basename|xargs -n1 -I{} find $PT_MYSQLBACKUPPATH/ -mtime +30 -name {} -delete

0

ขออภัยที่จะเปิดกระทู้เก่านี้อีกครั้ง แต่ฉันเพิ่งมีปัญหาที่คล้ายกันและไม่สามารถหาทางออกที่ดี

ในที่สุดฉันก็แก้ไขมันเช่นนี้:

cd /directory_where_things_need_removing
ls -tr1dQ * | head -n -31 | xargs rm -rf

ส่วนที่สำคัญคือ ls -tr1dQ โดยที่เครื่องหมายคำพูด Q แก้ปัญหาช่องว่างและ 1 ซึ่งให้ 1 โซลูชันต่อบรรทัด head -n -31 ซึ่งละเว้น 31 บรรทัดแรก (ในกรณีของฉัน = 1 เดือน) โปรดทราบว่า - ก่อนและก่อนจำนวนบรรทัดที่คุณต้องการเก็บ ทดสอบบน linux ทางวิทยาศาสตร์ 6.5


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