在Linux中,我使用InfluxDB,它可以为存档目的备份数据库。每个备份包含一系列具有相同前缀“ / tank / Backups / var / Influxdb / 20191225T235655Z”的文件。和不同的扩展名。
我想编写一个bash脚本,该脚本首先删除最旧的现有备份,然后创建一个新的备份(这里我仅粘贴删除的备份:]
ls -tp /tank/Backups/var/Influxdb/* | grep -v '/$' | sed -E 's/\..+//' | \
sort -ru | sed 's/$/.*/' | tail -n +4 | xargs -d '\n' -r rm --
但是,当我以“ sudo”运行脚本时,会得到
rm: cannot remove '/tank/Backups/var/Influxdb/20191225T235655Z.*': No such file or directory
当运行引用的脚本时,除最新部分外,我得到:
/tank/Backups/var/Influxdb/20190930T215357Z.*
/tank/Backups/var/Influxdb/20190930T215352Z.*
是正确的。另外,如果我手动写
sudo /tank/Backups/var/Influxdb/20190930T215357Z.*
命令成功。
为什么脚本报告错误?
我正在使用Ubuntu 18.04,文件夹“ / tank”是ZFS卷。
最好做:
find /tank/Backups/var/Influxdb/* -mtime +5 -delete
删除5天之前的文件。
然后,您可以运行下一个命令
此答案仅是为了解释该错误并更深入地了解正在发生的事情。如果您只是在寻找一种优雅的解决方案,请搜索其他答案。
当运行引用的脚本时,除最新部分外,我得到:
/tank/Backups/var/Influxdb/20190930T215357Z.* /tank/Backups/var/Influxdb/20190930T215352Z.*
是正确的
列出的字符串不是您想要的。当您将这些路径传递到rm
时,它们会像原义字符串一样看到它们,即,两个文件名以原义*
结尾的文件。由于您没有此类文件,因此会出现错误。
当您在控制台中手动输入rm *
时,bash
(不是rm
!)会globbing。 bash
搜索文件,并用找到的文件列表替换*
。仅在此之后,bash
才会执行rm foundFile1 foundFile2 ...
。 rm
从未看到*
。
bash
不会处理管道中的字符串,但rm
会处理管道中的命令。 rm
不起作用。
您可以在管道中运行bash
,并使其扩展先前插入的*
。为此,将管道中的最后一个命令替换为xargs -r bash -c 'rm -- $*' --
。但是,请注意,此处未引用您的路径。如果文件名中有空格或文字*
,该命令将中断。对于引用来说,这是必需的,因为引号"*"
不会被bash
扩展。
要引用文件,必须在bash命令中插入*
glob:
ls -tp /tank/Backups/var/Influxdb/* | grep -v '/$' | sed -E 's/\..+//' |
sort -ru | tail -n +4 | xargs -d\\n -L1 -r bash -c 'rm -- "$0."*'
以上命令只是您命令的简单修复。它既不优雅也不坚固。强烈建议使用find
之类的工具。