Câu hỏi Có gì sai với kịch bản bash của tôi để giữ các tập tin x cuối cùng và xóa phần còn lại?


Tôi có kịch bản bash này mà độc đáo sao lưu cơ sở dữ liệu của tôi trên một lịch trình 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

Vấn đề với điều này là nó sẽ tiếp tục bán các bản sao lưu trong thư mục và không dọn dẹp các tệp cũ. Đây là nơi biến PT_FILESTOKEEP Bất kể số này được đặt thành số lượng bản sao lưu mà tôi muốn giữ lại. Tất cả các bản sao lưu đều được đóng dấu thời gian nên bằng cách đặt hàng chúng theo tên, DESC sẽ cung cấp cho bạn bản mới nhất trước tiên.

Bất cứ ai có thể vui lòng giúp tôi với phần còn lại của tập lệnh BASH để thêm các tập tin sạch? Kiến thức của tôi về bash là thiếu và tôi không thể mảnh với nhau mã để làm phần còn lại.


7
2018-03-21 12:33


gốc




Các câu trả lời:


Trước tiên, hãy chắc chắn bạn đang ở trong thư mục bên phải:

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

Bạn có thể xóa các tệp cũ hơn n, trong trường hợp của bạn:

find -mtime +14 -delete

Xóa các tệp cũ hơn 14 ngày.

Giải pháp phức tạp hơn (chắc chắn không phải là tối ưu, mặc dù) cho câu hỏi của bạn:

# 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

9
2018-03-21 12:40



Đây không phải là những gì tôi đã thực sự sau nhưng thực sự sẽ làm việc tốt hơn so với những gì tôi đã có trong tâm trí. Trước khi tôi kiểm tra làm thế nào để đảm bảo điều này được chạy trong PT_MYSQLBACKUPPATH. Không muốn chạy điều này bên ngoài mà nếu không kết thúc xóa một tải toàn bộ các tập tin. Có thể là một thảm họa ... - Brady
@ Brady: Tôi đã thêm ví dụ để kiểm tra môi trường. - Olli
Đừng không bao giờ sử dụng for i in $(ls) hoặc là var=($(ls)) (Dấu: for i in *) trừ khi bạn có thể chắc chắn 400% rằng tên tập tin sẽ không bao giờ chứa khoảng trống hoặc bất cứ thứ gì như thế. - grawity
@Olli - Ok rằng kịch bản hiện đang làm việc mà không có lỗi tuy nhiên tôi sẽ không thể nói nếu việc xóa ngày 14 là làm việc cho đến khi tôi có một số tập tin cũ trong đó. Sẽ ghé thăm lại sau 14 ngày nếu có vấn đề. Cảm ơn đã giúp đỡ. - Brady
ls | sort sắp xếp theo Tên. Sử dụng ls -t | head -n 14 (nó vẫn sẽ thất bại, tuy nhiên, đối với tên tập tin có chứa khoảng trắng). - Dennis Williamson


Bạn có thể thử cái này:

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

ls -r1 sẽ liệt kê tất cả các tệp theo thứ tự ngược lại, một tệp trên mỗi dòng.

tail -n +$number lọc các tập tin $ number-1 đầu tiên của danh sách (resp. hiển thị tất cả các tập tin bắt đầu từ số $ đến số cuối cùng).

xargs sẽ thực thi rm với tất cả tên tệp từ đầu vào tiêu chuẩn.


11
2018-03-21 13:08



Cảm ơn bạn đã trả lời bmk nhưng tôi đã sử dụng tính năng tìm kiếm -mtime +14 -deletecung cấp bởi Olli - Brady
1 vì câu trả lời này rất chính xác. - DevSolar


Đây là cách sử dụng cảm hứng của tôi từ bài đăng này:

#!/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
2018-06-28 11:36





Về câu trả lời từ bmk, khi có ls -t1 an toàn hơn -r1 (sắp xếp theo thời gian sửa đổi thay vì thứ tự tệp tùy ý)

Ngoài ra trên một số phiên bản của cú pháp đuôi là tail -n +$number (tùy chọn -n là cần thiết)

Là tiền thưởng, kết hợp cả tìm kiếm và ls, đây là cách để xóa tệp cũ hơn 30 ngày nhưng giữ ít nhất 15 tệp:

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

3
2018-06-02 17:31





xin lỗi để mở lại chủ đề cũ hơn này, nhưng tôi đã có một vấn đề tương tự gần đây và không thể tìm thấy một giải pháp tốt.

Cuối cùng tôi đã giải quyết nó như thế này:

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

các bộ phận quan trọng là ls -tr1dQ trong đó dấu ngoặc kép Q, giải quyết vấn đề khoảng trắng và 1 cho 1 giải pháp trên mỗi dòng. đầu -n -31 mà OMITS trong 31 dòng đầu tiên (trong trường hợp của tôi = 1 tháng). xin lưu ý - trước n và trước số dòng bạn muốn giữ. thử nghiệm trên linux khoa học 6.5


0
2017-08-04 12:04





ls -t /path/* | grep -v "$(ls -t /path/* | head -6)" | xargs rm -f

-1
2017-08-12 18:15



Một số giải thích về mã bạn đăng sẽ rất tuyệt. Bạn có thể chỉnh sửa câu trả lời của bạn? - slhck