首先,以下是每日备份文件的文件名示例:
website-db-backup06-June-2020.tar.gz
通过终端手动运行时,下面的脚本运行良好。但是,当脚本通过 cron 运行时,我在电子邮件中收到此 cron 守护进程消息:
tar: website-db-backup*: Cannot stat: No such file or directory
tar: Exiting with failure status due to previous errors
这是我每周压缩所有日常备份的脚本:
#!/bin/bash
#
# Weekly compression for database backups
BACKUP_PATH=~/backup/web/database
BACKUP_FILE_DATE=`date '+%d-%B-%Y'`
tar -czf $BACKUP_PATH/website-db-weekly-compress$BACKUP_FILE_DATE.tar.gz \
-C $BACKUP_PATH/ website-db-backup* && rm $BACKUP_PATH/website-db-backup*
由于每日备份有date
文件名,我必须*
在脚本上使用。这可能是原因吗?
答案1
问题是脚本的当前工作目录。website-db-backup*
没有路径,因此在当前目录中执行。您必须在脚本中添加如下内容:
SOURCE_DIR_PATH='/path/to/backup_source'
cd "$SOURCE_DIR_PATH" || exit 1
此外,在执行之前您应该检查是否有任何匹配的文件tar
:
shopt -s nullglob
set -- website-db-backup*
test $# -eq 0 && { echo 'ERROR: No matching files; aborting'; exit 1; }
在这种情况下,这可能不是问题,但正如 danielleontiev 在评论中指出的那样,~
如果该脚本可能由不同用户执行,则在脚本中使用是危险的。我建议你将其替换为预期的路径。
答案2
使用failglob
是另一种选择,其中全局扩展失败将导致整个命令失败(根本不执行任何操作)。与 shell 的无操作运算符:
(冒号)相结合,这是测试 glob 结果(成功与否)的完美方法。
shopt -s failglob
: website-db-backup*
# The following code is purely indicative
if [ $? -eq 0 ]; then
echo "Success, website-db-backup* exists"
else
echo "Failed, nothing matches website-db-backup*"
fi
这比豪克·拉金的回答在那里面它不会破坏现有的位置参数($1
等),尽管您可以通过使用函数来解决这个问题:
shopt -s nullglob
argc() {
return $#
}
argc website-db-backup*
# Now check $? the same way as above
# $1, $2, ... remain untouched
Bash 数组也是一个不错的选择:
shopt -s nullglob
FILES=(website-db-backup*)
echo "${#FILES[@]}" # gives number of matched files
在我看来,这是最简单、最优雅的解决方案。