作为 cronjob 运行时脚本未按预期工作

作为 cronjob 运行时脚本未按预期工作

首先,以下是每日备份文件的文件名示例:

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

在我看来,这是最简单、最优雅的解决方案。

相关内容