我的 /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}'
对我有用。