最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

如何在

旗下网站admin26浏览0评论

如何在

如何在

如何在-exec中获取basename?(how to get basename in -exec of find?)

我无法获得以下脚本(这是更大的备份脚本的一部分)才能正常工作:

BACKUPDIR=/BACKUP/db01/physical/incremental # Backups base directoryFULLBACKUPDIR=$BACKUPDIR/full # Full backups directoryINCRBACKUPDIR=$BACKUPDIR/incr # Incremental backups directoryKEEP=5 # Number of full backups (and its incrementals) to keep...FIRST_DELETE=`expr $KEEP + 1` # add one to the number of backups to keep, this will be the first deletedFILE0=`ls -ltr $FULLBACKUPDIR | awk '{print $9}' | tail -$FIRST_DELETE | head -1` # search for the first backup to be 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 {})' \;

所以这个查找工作正常,它本身会输出这样的东西:

/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

我想要的是-exec回显显示正在删除的行,然后从两个目录中删除该文件夹。

我已经尝试了各种方法来获得基本名称,但似乎没有任何工作。 我明白了:

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"

当然,文件夹不会被删除,因为它们不存在,只是因为-f选项而无声地失败。 如果我删除-f,我会在每个rm上找到“无法找到”错误。

我该如何做到这一点? 由于备份和部分备份可能存储在不同的存储系统中,因此我真的需要能够获取文件夹名称以便在任何已知路径中使用。

I cannot get the following piece of script (which is part of a larger backup script) to work correctly:

BACKUPDIR=/BACKUP/db01/physical/incremental # Backups base directoryFULLBACKUPDIR=$BACKUPDIR/full # Full backups directoryINCRBACKUPDIR=$BACKUPDIR/incr # Incremental backups directoryKEEP=5 # Number of full backups (and its incrementals) to keep...FIRST_DELETE=`expr $KEEP + 1` # add one to the number of backups to keep, this will be the first deletedFILE0=`ls -ltr $FULLBACKUPDIR | awk '{print $9}' | tail -$FIRST_DELETE | head -1` # search for the first backup to be 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 the find works correctly which on its own will output something like 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 I want is the -exec to echo a line showing what is being removed and then remove the folder from both directories.

I've tried various ways to get just the basename but nothing seems to be working. I get 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 the folders arn't deleted because they don't exist, just fail silently because of the -f option. If I remove the -f I get the 'cannot be found' error on each rm.

How do I accomplish this? Because backups and parts of backups may be stored across different storage systems I really need the ability to just get the folder name for use in any known path.

最满意答案

这里有很多破碎。

所有大写变量都是按照惯例env变量,不应在脚本中使用。 使用遗留反引号而不是$() 解析ls (!)的输出 解析ls -l的输出(!!!) 扩展已知包含没有完整引号的路径的变量。

为了改善这一点,你绝对需要的是-exec bash ,例如

-execdir bash -c 'filepath="$1" ; base=$(basename "$filepath") ; echo use $filepath and $base here' -- {} \;

但是相反如何:

#!/usr/bin/env bashbackup_base=/BACKUP/db01/physical/incrementalfull_backup="$backup_base"/fullincremental_backup="$backup_base"/incrkeep=5rm=echolet n=0while IFS= read -r -d $'\0' line ; do file="${line#* }" if [[ $n -lt $keep ]] ; then 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)

迭代备份目录下的文件和目录,跳过最新的5个。 从与其余名称匹配的完整和增量目录文件中删除。

这是一个基本上安全的版本,当然除了定时攻击。

我已经将rm定义为echo以避免意外删除; 一旦你确定它是正确的,将它交换回rm进行实际删除。

Lots of broken here.

All caps variables are by convention env vars and should not be used in scripts. Using legacy backticks instead of $() Parsing the output of ls (!) Parsing the output of ls -l (!!!) Expanding variables known to contain paths without full quotes.

All you absolutely need in order to improve this is to -exec bash properly, e.g.

-execdir bash -c 'filepath="$1" ; base=$(basename "$filepath") ; echo use $filepath and $base here' -- {} \;

But how about this instead:

#!/usr/bin/env bashbackup_base=/BACKUP/db01/physical/incrementalfull_backup="$backup_base"/fullincremental_backup="$backup_base"/incrkeep=5rm=echolet n=0while IFS= read -r -d $'\0' line ; do file="${line#* }" if [[ $n -lt $keep ]] ; then 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 over files and directories immediately under the backup dir and skip the first 5 newest. Delete from the full and incremental dirs files matching the names of the rest.

This is an essentially safe version, except of course for timing attacks.

I have defined rm as being echo to avoid accidental deletes; swap it back to rm for actual deletion once you're sure it's correct.

发布评论

评论列表(0)

  1. 暂无评论