У меня в /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 {} \;
Когда я запускаю сценарий clean-nexus-release-repo.sh из своей оболочки, все работает нормально. Когда он запускается через cron, я получаю следующий результат:
find: Invalid range end
find: Invalid range end
Это та же ошибка, которую я получаю, когда перемещаю дефис в [a-Z0-9_.-]
регулярное выражение в недопустимую позицию. Я пробовал следующее, но все равно получаю ту же ошибку:
find --version
дает:
find (GNU findutils) 4.4.2
Работает в Linux devtools01 2.6.32-71.el6.x86_64 (CentOS Linux, выпуск 6.0)
[a-Z] работает, как задумано, с языковым стандартом fr_FR.UTF-8 и, вероятно, со всеми языковыми стандартами UTF8, но не с языковым стандартом "C", как было сказано ранее.
Сценарий, запускаемый из cron, не наследует языковой стандарт, тогда как тот же сценарий, протестированный из командной строки, наследует языковой стандарт пользователя (xx_XX.UTF-8). Это объясняет различное поведение.
Я не уверен, что смогу дать здесь идеальное техническое объяснение. может кто-нибудь еще может улучшить ответ.
в основном я помню, что выражения диапазона зависят от локали, поэтому [a-Z] не обязательно означает то же, что и [a-zA-Z]
Я думаю, что соответствующая документация:
http://www.gnu.org/software/grep/manual/grep.html#index-range-expression-216:
В выражении в квадратных скобках выражение диапазона состоит из двух символов, разделенных дефисом. Он соответствует любому одиночному символу, который выполняет сортировку между двумя символами, включительно, с использованием последовательности сортировки и набора символов локали. Например, в локали C по умолчанию «[a-d]» эквивалентно «[abcd]». Многие языковые стандарты сортируют символы в словарном порядке, и в этих языковых стандартах «[a-d]» обычно не эквивалентно «[abcd]»; он может быть, например, эквивалентом «[aBbCcDd]». Чтобы получить традиционную интерпретацию выражений в квадратных скобках, вы можете использовать локаль «C», установив для переменной среды LC_ALL значение «C».
Хорошо, я думаю, что проблема обнаружена в способе определения диапазонов. a-Z означает от значения ascii «a» (97) до значения ascii «Z» (90), что означает, что диапазон заканчивается раньше, чем начинается.
Почему это работает в оболочке, я не уверен, но меняя регулярное выражение с
-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}'
работает для меня.