在 cron 中运行包含带有正则表达式的 find 的脚本会失败,但在 shell 中可以运行

在 cron 中运行包含带有正则表达式的 find 的脚本会失败,但在 shell 中可以运行

我的 /etc/cron.d 中有以下脚本:

19 15 * * * root /opt/scripts/clean-nexus-release-repo.sh

clean-nexus-release-repo.sh 脚本如下所示:

#!/bin/bash
find /opt/sonatype-work/nexus/storage/releases/se/company* -regextype posix-extended -depth -regex '.*/r?[0-9]{5,7}[a-Z0-9_.-]*\.[0-9]{1,3}' -mtime +60 -type d -print -exec rm -r {} \;
find /opt/sonatype-work/nexus/storage/releases/nu/company -regextype posix-extended -depth -regex '.*/r?[0-9]{5,7}[a-Z0-9_.-]*\.[0-9]{1,3}' -mtime +60 -type d -print -exec rm -r {} \;

当我从 shell 运行 clean-nexus-release-repo.sh 脚本时,一切正常。当通过 cron 运行时,我得到以下输出:

find: Invalid range end
find: Invalid range end

当我将正则表达式中的连字符移动到无效位置时,我得到的错误也是一样的[a-Z0-9_.-]。我尝试了以下方法,但仍然得到同样的错误:

  • 指定 find 命令的绝对路径
  • 使用反斜杠转义连字符
  • 删除连字符

find --version给出:

find (GNU findutils) 4.4.2

在 Linux devtools01 2.6.32-71.el6.x86_64(CentOS Linux 版本 6.0)上运行

答案1

我不确定我能否在这里给出完美的技术解释。也许其他人可以改进答案。

基本上我记得范围表达式取决于语言环境,因此 [aZ] 不一定与 [a-zA-Z] 含义相同

我认为相关文献是:

http://www.gnu.org/software/grep/manual/grep.html#index-range-expression-216

在括号表达式中,范围表达式由两个字符组成,两个字符之间用连字符分隔。它使用语言环境的排序顺序和字符集匹配排序在两个字符(含)之间的任何单个字符。例如,在默认的 C 语言环境中,“[ad]”相当于“[abcd]”。许多语言环境按字典顺序对字符进行排序,在这些语言环境中,“[ad]”通常不等同于“[abcd]”;例如,它可能等同于“[aBbCcDd]”。要获得括号表达式的传统解释,可以通过将 LC_ALL 环境变量设置为值“C”来使用“C”语言环境。

答案2

[aZ] 可以按预期在语言环境 fr_FR.UTF-8 下工作,并且可能在所有 UTF8 语言环境下工作,但是不能在“C”语言环境下工作,正如前面所回答的。

从 cron 运行的脚本不继承任何语言环境,而从命令行测试的相同脚本则继承用户语言环境 (xx_XX.UTF-8)。这解释了不同的行为。

答案3

好的,我认为问题在于范围的定义方式。aZ 表示从 ascii 值“a”(97) 到 ascii 值“Z”(90),这意味着范围在开始之前就结束。

我不确定为什么它在 shell 中起作用,但是将正则表达式从

-regex '.*/r?[0-9]{5,7}[a-Z0-9_.-]*\.[0-9]{1,3}'

-regex '.*/r?[0-9]{5,7}[a-zA-Z0-9_.-]*\.[0-9]{1,3}'

对我有用。

相关内容