Initial commit
This commit is contained in:
		
							
								
								
									
										110
									
								
								binary_backups.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										110
									
								
								binary_backups.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,110 @@ | |||||||
|  | #!/bin/bash | ||||||
|  |  | ||||||
|  | # These knobs control which backups to keep, and how long to keep them for. A | ||||||
|  | # backup is kept if its distance from the UNIX epoch in days divides evenly by | ||||||
|  | # BASE^power (where power is some integer 0 < MAX_POWER), and it is less than | ||||||
|  | # WINDOW_FACTOR*BASE^power days old. | ||||||
|  | BASE=2 | ||||||
|  | MAX_POWER=16 | ||||||
|  | WINDOW_FACTOR=4 | ||||||
|  |  | ||||||
|  | # Returns output if the date passed in as the first argument is not in a format | ||||||
|  | # 'date' can understand | ||||||
|  | function invalid_date() { | ||||||
|  |   date -d "$1 + 1 min" +"%s" &> /dev/null | ||||||
|  |   if [[ $? -ne 0 ]]; then | ||||||
|  |     echo "invalid" | ||||||
|  |   fi | ||||||
|  | } | ||||||
|  |  | ||||||
|  | # Return the number of days which passed between the UNIX epoch and the first | ||||||
|  | # argument | ||||||
|  | function days_since_epoch() { | ||||||
|  |   echo $(( $(date -d "$1" +"%s") / (60*60*24) )) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | # Prints "keep" if the backup with the indicated date should be kept | ||||||
|  | function keep_backup() { | ||||||
|  |   local current_day_count=$1 | ||||||
|  |   local backup_day_count=$2 | ||||||
|  |   local difference=$(( $current_day_count - $backup_day_count )) | ||||||
|  |  | ||||||
|  |   for (( power=0; power<=$MAX_POWER; power++ )); do | ||||||
|  |     local factor=$(( $BASE ** $power )) | ||||||
|  |     local remainder=$(( $backup_day_count % $factor )) | ||||||
|  |     if [[ $remainder -eq 0 ]] && | ||||||
|  |         [[ $difference -le $(($factor * $WINDOW_FACTOR)) ]]; then | ||||||
|  |       echo "keep" | ||||||
|  |       return | ||||||
|  |     fi | ||||||
|  |   done | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function usage() { | ||||||
|  | cat << EOF | ||||||
|  | Usage: $0 options | ||||||
|  |  | ||||||
|  | Print the backups which should (or should not with -r) be kept from a list of | ||||||
|  | dates passed via stdin. | ||||||
|  |  | ||||||
|  | OPTIONS: | ||||||
|  |    -h       Show this message | ||||||
|  |    -i FILE  Read candidate backup dates from FILE instead of stdin | ||||||
|  |    -d DATE  Calculate which backups should be kept from this date instead of | ||||||
|  |             today  | ||||||
|  |    -r       Reverse which dates are displayed (show those which should be | ||||||
|  |             deleted instead of kept) | ||||||
|  | EOF | ||||||
|  | } | ||||||
|  |  | ||||||
|  | reverse= | ||||||
|  | current_date=$(date -I) | ||||||
|  | input="/dev/stdin" | ||||||
|  |  | ||||||
|  | while getopts "hrd:i:" OPTION; do | ||||||
|  |   case $OPTION in | ||||||
|  |     i) | ||||||
|  |       input=$OPTARG | ||||||
|  |       if [[ ! -f $input ]]; then | ||||||
|  |         echo "Error: \"$input\" is not a file" | ||||||
|  |         usage | ||||||
|  |         exit 1 | ||||||
|  |       fi | ||||||
|  |       ;; | ||||||
|  |     d) | ||||||
|  |       current_date=$OPTARG | ||||||
|  |       if [[ $(invalid_date "$current_date") ]]; then | ||||||
|  |         echo "Error: \"$current_date\" is not a valid date" | ||||||
|  |         usage | ||||||
|  |         exit 1 | ||||||
|  |       fi | ||||||
|  |       ;; | ||||||
|  |     r) | ||||||
|  |       reverse="true" | ||||||
|  |       ;; | ||||||
|  |     h) | ||||||
|  |       usage | ||||||
|  |       exit | ||||||
|  |       ;; | ||||||
|  |     ?) | ||||||
|  |       usage | ||||||
|  |       exit 1 | ||||||
|  |       ;; | ||||||
|  |   esac | ||||||
|  | done | ||||||
|  |  | ||||||
|  | current_days=$(days_since_epoch "$current_date") | ||||||
|  |  | ||||||
|  | while read line; do | ||||||
|  |   if [[ $(invalid_date "$line") ]]; then | ||||||
|  |     echo "Error: \"$line\" is not a valid date" | ||||||
|  |     exit 1 | ||||||
|  |   fi | ||||||
|  |   backup_days=$(days_since_epoch "$line") | ||||||
|  |   keep=$(keep_backup $current_days $backup_days) | ||||||
|  |   if [[ -z $reverse ]] && [[ $keep ]]; then | ||||||
|  |     echo $line | ||||||
|  |   elif [[ $reverse ]] && [[ -z $keep ]]; then | ||||||
|  |     echo $line | ||||||
|  |   fi | ||||||
|  | done < $input | ||||||
		Reference in New Issue
	
	Block a user