Уважаемые господа, помогите пожалуйста разобраться с экранированием в crontab.Общий вопрос в том, что комманда (трехэтажная) прекрасно запускается и работает из командной строки, но не работает когда ее помещаю в crontab.
Как я понимаю, нужно сделать правильное экранирование символов, а вот как именно, не совсем понятно.Вот комманда:
cd /mnt/sdb/report; ls -1 | sed '/tbz2/d; /$(date --date=6\ months\ ago +%Y%m)/,\$d' | xargs -n 1 -I {} tar cjpf {}.tbz2 {} --remove-filesее смысл:
есть директории вида YYYYMMDD, нужно выбрать те, которые старше 6-ти месяцев и сжать tar-ом, каждую в свой файл.
ls -1 выводит в алфавитном порядке
sed выкидываем архивы и то что новее 6-ти месяцев
date --date=6\ months\ ago +%Y%m дает месяц 6 месяцев назадна xargs и т.д. можно не обращать внимания
В crontab пишу так:
0 3 1 * * cd /mnt/sdb/report; ls -1 | sed '/tbz2/d; /$(date --date=6\ months\ ago +%Y%m)/,\$d' | xargs -n 1 -I {} tar cjpf {}.tbz2 {} --remove-filesполучаю ошибку:
/bin/sh: -c: line 0: unexpected EOF while looking for matching `''
/bin/sh: -c: line 1: syntax error: unexpected end of file
Велосипед, такой велосипед...
find /mnt/sdb/report -maxdepth 1 -type d -mtime +183 | while read i ; do tar cjvf "/mnt/sdb/report/$i.tbz2" "$i" ; rm -fr "$i"; done
> Велосипед, такой велосипед...
> -mtime +183не годится, все даты не соответствуют ничему
цепляться можно только за имя каталога
Написать скрипт, отладить, в кронтабе запускать уже скрипт.
> Написать скрипт, отладить, в кронтабе запускать уже скрипт.Суть в том, что в командной строке у Вас скорее всего bash, а crontab, судя по логам ошибки, использует /bin/sh
>> Написать скрипт, отладить, в кронтабе запускать уже скрипт.
> Суть в том, что в командной строке у Вас скорее всего bash,
> а crontab, судя по логам ошибки, использует /bin/shВы правы, поэтому для отладки я запускаю так:
/bin/sh -c "cd /mnt/sdb/report; ls -1 | sed '/tbz2/d; /$(date --date=6\ months\ ago +%Y%m)/,\$d' | xargs -n 1 -I {} echo tar cjpf {}.tbz2 {}"И получаю такой вывод:
tar cjpf 20120401.tbz2 20120401
tar cjpf 20120402.tbz2 20120402
...
tar cjpf 20120430.tbz2 20120430То есть все работает как надо.
> Написать скрипт, отладить, в кронтабе запускать уже скрипт.Так тоже работает. Мой вопрос, как и какие символы правильно экранировать, чтобы это работало и из кронтаба.
>> Написать скрипт, отладить, в кронтабе запускать уже скрипт.
> Так тоже работает. Мой вопрос, как и какие символы правильно экранировать, чтобы
> это работало и из кронтаба.$whoami
$echo $PATH
$su
..
#echo $PATHуказать полные пути к командам.
>> Велосипед, такой велосипед...
>> -mtime +183
> не годится, все даты не соответствуют ничему
> цепляться можно только за имя каталогаНу и что?
a=$(date --date=6\ months\ ago +%Y%m)00 ; cd /mnt/sdb/report; ls | while read i; do if [ "$i" -lt "$a" ]; then tar cjvf "$i.tbz2" "$i"; rm -fr "$i"; done
>>> Велосипед, такой велосипед...
>>> -mtime +183
>> не годится, все даты не соответствуют ничему
>> цепляться можно только за имя каталога
> Ну и что?
> a=$(date --date=6\ months\ ago +%Y%m)00 ; cd /mnt/sdb/report; ls | while read
> i; do if [ "$i" -lt "$a" ]; then tar cjvf
> "$i.tbz2" "$i"; rm -fr "$i"; doneТо же самое, ошибка:
/bin/sh: -c: line 0: unexpected EOF while looking for matching `)'
/bin/sh: -c: line 1: syntax error: unexpected end of fileВашу строку я даже руками не могу запустить, так как она содержит кавычки:
/bin/sh -c "комманда"
> Уважаемые господа, помогите пожалуйста разобраться с экранированием в crontab.
> Общий вопрос в том, что комманда (трехэтажная) прекрасно запускается и работает из
> командной строки, но не работает когда ее помещаю в crontab.
> Как я понимаю, нужно сделать правильное экранирование символов, а вот как именно,
> не совсем понятно.
> есть директории вида YYYYMMDD, нужно выбрать те, которые старше 6-ти месяцев и
> сжать tar-ом, каждую в свой файл.Итак, результаты изысканий:
1. crontab не пропускает конструкции `команда` и $(команда)
2. не нравится символ + в параметрах команды dateРаботающий итог следующий:
cd /mnt/sdb/report; (/bin/date --date=6\ months\ ago -I | sed 's/-//; s/-.*$/!!/'; ls -1 | sed -n '/^[0-9]\{8\}$/p') | sort | sed '/!!/,$d' | xargs -n 1 -I {} tar cjpf {}.tbz2 {} --remove-files
Краткое пояснение (для себя ;-))
Дает дату 6 месяцев назад в виде YYYYMM!!
/bin/date --date=6\ months\ ago -I | sed 's/-//; s/-.*$/!!/'Список всего вида YYYYMMDD, у меня это каталоги. Специально сделал так, чтобы ничего лишнего случайно не обработалось, мало ли что там появится в будущем.
ls -1 | sed -n '/^[0-9]\{8\}$/p'После сортировки этого строка YYYYMM!! оказывается между списком того, что старее 6-ти месяцев и тем, что новее, соответственно удаляем из списка все от этой строки до конца:
sed '/!!/,$d'Ну а дальше - дело техники: на входе список на выходе архивы:
xargs -n 1 -I {} tar cjpf {}.tbz2 {} --remove-filesВсем спасибо за участие)
>> Уважаемые господа, помогите пожалуйста разобраться с экранированием в crontab.
>> Общий вопрос в том, что комманда (трехэтажная) прекрасно запускается и работает из
>> командной строки, но не работает когда ее помещаю в crontab.
>> Как я понимаю, нужно сделать правильное экранирование символов, а вот как именно,
>> не совсем понятно.
>> есть директории вида YYYYMMDD, нужно выбрать те, которые старше 6-ти месяцев и
>> сжать tar-ом, каждую в свой файл.
> Итак, результаты изысканий:
> 1. crontab не пропускает конструкции `команда` и $(команда)а должен? задайте себе вопрос под каким шелом крон работает и под каким Вы тестировали скрипт.
> 2. не нравится символ + в параметрах команды date
экранировать в соответсвии с праилами шела, который использует крон.
>[оверквотинг удален]
> ничего лишнего случайно не обработалось, мало ли что там появится в
> будущем.
> ls -1 | sed -n '/^[0-9]\{8\}$/p'
> После сортировки этого строка YYYYMM!! оказывается между списком того, что старее 6-ти
> месяцев и тем, что новее, соответственно удаляем из списка все от
> этой строки до конца:
> sed '/!!/,$d'
> Ну а дальше - дело техники: на входе список на выходе архивы:
> xargs -n 1 -I {} tar cjpf {}.tbz2 {} --remove-files
> Всем спасибо за участие)
>> 1. crontab не пропускает конструкции `команда` и $(команда)
> а должен? задайте себе вопрос под каким шелом крон работает и под
> каким Вы тестировали скрипт.
>> 2. не нравится символ + в параметрах команды date
> экранировать в соответсвии с праилами шела, который использует крон.Вы все правильно говорите, буду очень признателен, если вы сможете написать мне правильно экранированную сроку для crontab хотя бы одной из этих команд (или всех, если у вас это получится):
my_date=`date`
my_date=$(date)
date +%Y%m
>[оверквотинг удален]
>> а должен? задайте себе вопрос под каким шелом крон работает и под
>> каким Вы тестировали скрипт.
>>> 2. не нравится символ + в параметрах команды date
>> экранировать в соответсвии с праилами шела, который использует крон.
> Вы все правильно говорите, буду очень признателен, если вы сможете написать мне
> правильно экранированную сроку для crontab хотя бы одной из этих команд
> (или всех, если у вас это получится):
> my_date=`date`
> my_date=$(date)
> date +%Y%m1)
[root@local ~]# whereis date
date: /bin/datemy_date=`/bin/date`
my_date=$(/bin/date)
/bin/date +%Y%mЧитайте то, что Вам выше писали про пути. Я уже пытался показать Вам, что для разных пользователей $PATH отличется. У crona PATH по умолчанию (как правило) просто нет.
2)
По умолчанию cron пускает скрипты под оболочкой sh, но что у Вас за система и что там накручено - бог знает - инфы нет. Под sh из командной строки Вы проверяли. Значит дело в п.1 или в том, что используется другой шелл - вопрос какой (для того чтобы с экранированием и прочим разобраться).3)
если файловая система с bash-ем (или другой любимой Вами оболочкой) на момент запуска команды гарантировано доступна, то никто не мешает явно указать /bin/bash в качестве шела для кроновской команды (так же как Вы при тесте использовали /bin/sh)PS
покажите уже наверно cat /etc/crontab, чтобы не пригодилось на кофейной гуще гадать.
> [root@local ~]# whereis dateочень правильно, для крона - только так.
> my_date=`/bin/date`
правильно и кроссплатформенно (гы - православно!).
> my_date=$(/bin/date)
только под линуксы ну и где ещё sh=bash
> /bin/date +%Y%m
неправильно, правильно /bin/date '+%Y%m'
>> [root@local ~]# whereis date
> очень правильно, для крона - только так.
>> my_date=`/bin/date`
> правильно и кроссплатформенно (гы - православно!).
>> my_date=$(/bin/date)
> только под линуксы ну и где ещё sh=bash
>> /bin/date +%Y%m
> неправильно, правильно /bin/date '+%Y%m'похрену сама команда и ее синтаксис в этом конкретном случае - суть в том, что путь к ней полностью прописать надо.