2014-02-14 2 views
1

Когда я использую это:Оператор if-else работает неправильно в crontab?

*/5 6-18 * * 1-6 [ "$(ls -A /DIR_WHERE_FILES_ARE_OR_NOT/)" ] && 
    rsync -au /DIR_WHERE_FILES_ARE_OR_NOT/ /DIR_WHERE_FILES_SHOLD_GO; \ 
    mv /DIR_WHERE_FILES_ARE_OR_NOT/* /SAVE_DIR/ || 
    mail -s "DIR IS EMPTY" [email protected] <<< "message" 

я получаю два письма:

мв: не может стат `/ DIR_WHERE_FILES_ARE_OR_NOT/* ': Нет такого файла или каталог

и

"DIR IS EMETTY"

Почему?

+2

Что о наличии надлежащего сценария с этими условиями и вызвав ее кронтаб ? Как это довольно сложно отслеживать и поддерживать. – fedorqui

+0

Спасибо! :) Теперь я изменил две команды на {}, но это не помогает – user3310114

+0

Только если я объявление выход 0; Позади двух коммандов, я доставляю сообщение об ошибке, но когда файлы находятся в DIR, я получаю сообщение об ошибке: /bin/sh: -c: строка 0: ошибка синтаксиса около неожиданного токена '} ' – user3310114

ответ

2

Вы

mv: cannot stat `/DIR_WHERE_FILES_ARE_OR_NOT/*': No such file or directory 

именно по указанной причине: этот каталог пуст, поэтому он не содержит файл с именем * (звездочка). Это просто способ расширения glob в оболочке: если glob ничего не соответствует, он передается буквально команде. Поскольку mv пытается переименовать несуществующий файл, он жалуется, как показано.

Это все был бы гораздо более удобным для чтения, если вместо последовательности && и || операторов в кронтабе вы бы поместить всю логику в сценарии с эквивалентными if/else/fi конструкциями и просто вызовите скрипт из хрон.

Вы получаете две письма, потому что вы явно отправляете первый номер с mail -s. Второй - от cron, потому что вывод на stderr и stdout не пуст.

Ваши команды эквивалентны

if [ "$(ls ...)" ]; then 
    rsync 
fi 
if ! mv; then 
    mail 
fi 

Обратите внимание, что нет else.

+0

Но почему crontab не только оператор if или else? – user3310114

+1

Из-за приоритета '&&' против '||'. – Jens

+0

Чтобы уточнить, из-за короткозамкнутой семантики в сочетании с точкой с запятой. В языке грамматики оболочки точка с запятой делает эти два отдельных * AND-OR-lists *. Во втором списке 'mv || mail', оба выполняются, потому что 'mv' терпит неудачу. – Jens

1

Вы получаете две письма, потому что, когда mv терпит неудачу, cron захватывает то, что написано в стандартной ошибке, и отправляет его владельцу, затем запускает команду mail. Вы можете подавить сообщение об ошибке от mv, чтобы избежать почты с cron.

mv /DIR_WHERE_FILES_ARE_OR_NOT/* /SAVE_DIR/ 2> /dev/null || mail -s "DIR IS EMPTY" [email protected] <<< "message" 
+0

Когда 'mv' терпит неудачу,' mv' пишет stderr, а не 'cron'. – Jens

+0

Я знал, что я плохо формулирую, но не понял, как плохо. – chepner

0

Как пользователь Jens уже упоминалось, а также из моего опыта, если вы не используете очень простой и, как правило, одну команду, вы должны придерживаться файлов сценариев. Итак, в вашем случае я бы пошел с файлом сценария. Я приведу вам пример.

#!/bin/bash 

dir_where_files_are_or_not=/filespath 
dir_where_files_should_go=/another/filespath 
save_dir=/savefiles/path 

# ok, lets start by checking if dir contains files 
if [ "$(ls -A $dir_where_files_are_or_not)" ]; then 
    # dir contains files, so lets rsync and mv them 
    rsync -au $dir_where_files_are_or_not/ $dir_where_files_should_go 
    mv $dir_where_files_are_or_not/* $save_dir 
else 
    # dir is empty, lets send email 
    mail -s "DIR IS EMPTY" [email protected] <<< "message" 
fi 

Теперь я просто поместил этот код в файл. Дайте ему имя, например «chkfiles» и сохраните его в каталоге (я использую/usr/local/sbin для всех моих скриптов).

Далее в командной строке запустите команду chmod +x /usr/local/sbin/chkfiles, чтобы сделать файл исполняемым. Затем добавьте скрипт к вашему crontab.

Я хотел бы предложить следующую строку внутри кронтаб:

*/5 6-18 * * 1-6 /bin/bash /usr/local/sbin/chkfiles 

Я использовал/bin/Баш, чтобы вызвать правильный интерпретатор для этого сценария. Теперь он должен работать должным образом.

Важные замечания:

  1. Перед запуском скрипта вам необходимо изменить dir_where_files_are_or_not, dir_where_files_should_go и save_dir ВАР к вашим потребностям.
  2. ли НЕ включают слеш в директориях, в противном случае Rsync и мв не могут делать то, что вы действительно хотите

С уважением

Смежные вопросы