bash - how to get basename in -exec of find? -
i cannot following piece of script (which part of larger backup script) work correctly:
backupdir=/backup/db01/physical/incremental # backups base directory fullbackupdir=$backupdir/full # full backups directory incrbackupdir=$backupdir/incr # incremental backups directory keep=5 # number of full backups (and incrementals) keep ... first_delete=`expr $keep + 1` # add 1 number of backups keep, first deleted file0=`ls -ltr $fullbackupdir | awk '{print $9}' | tail -$first_delete | head -1` # search first backup deleted ... find $fullbackupdir -maxdepth 1 -type d ! -newer $fullbackupdir/$file0 -execdir echo "removing: "$fullbackupdir/$(basename {}) \; -execdir bash -c 'rm -rf $fullbackupdir/$(basename {})' \; -execdir echo "removing: "$incrbackupdir/$(basename {}) \; -execdir bash -c 'rm -rf $incrbackupdir/$(basename {})' \;
so find works correctly on own output this:
/backups/db01/physical/incremental/full/2013-08-12_17-51-28 /backups/db01/physical/incremental/full/2013-08-12_17-51-28 /backups/db01/physical/incremental/full/2013-08-12_17-25-07
what want -exec echo line showing being removed , remove folder both directories.
i've tried various ways basename nothing seems working. this:
removing: /backups/mysql/physical/incremental/full/"/backups/mysql/physical/incremental/full/2013-08-12_17-51-28" removing: /backups/mysql/physical/incremental/incr/"/backups/mysql/physical/incremental/full/2013-08-12_17-51-28" removing: /backups/mysql/physical/incremental/full/"/backups/mysql/physical/incremental/full/2013-08-12_17-25-07"
and of course folders arn't deleted because don't exist, fail silently because of -f option. if remove -f 'cannot found' error on each rm.
how accomplish this? because backups , parts of backups may stored across different storage systems need ability folder name use in known path.
lots of broken here.
- all caps variables convention env vars , should not used in scripts.
- using legacy backticks instead of
$()
- parsing output of
ls
(!) - parsing output of
ls -l
(!!!) - expanding variables known contain paths without full quotes.
all absolutely need in order improve -exec bash
properly, e.g.
-execdir bash -c 'filepath="$1" ; base=$(basename "$filepath") ; echo use $filepath , $base here' -- {} \;
but how instead:
#!/usr/bin/env bash backup_base=/backup/db01/physical/incremental full_backup="$backup_base"/full incremental_backup="$backup_base"/incr keep=5 rm=echo let n=0 while ifs= read -r -d $'\0' line ; file="${line#* }" if [[ $n -lt $keep ]] ; let n=n+1 continue fi base=$(basename "$file") echo "removing: $full_backup/$base" "$rm" -rf -- "$full_backup"/"$base" echo "removing: $incremental_backup/$base" "$rm" -rf -- "$incremental_backup"/"$base" done < <(find "$full_backup" -maxdepth 1 -printf '%t@.%p\0' 2>/dev/null | sort -z -r -n -t. -k1,2)
iterate on files , directories under backup dir , skip first 5 newest. delete full , incremental dirs files matching names of rest.
this safe version, except of course timing attacks.
i have defined rm
being echo
avoid accidental deletes; swap rm
actual deletion once you're sure it's correct.
Comments
Post a Comment