Я использую vps-серверы от centos до ubuntu. Из-за сообщества (jeej мой первый вопрос к этому сообществу).
У меня есть cronjobs, отлично работающий на моих центровых vps, таких как:
01 22 * * * source /home/crawler2/env/bin/activate && cd /home/crawler2/project_spiderrooy && scrapy crawl spiderrooy > /home/crawler2/logs/spiderrooy_log_$(date '+\%Y-\%m-\%d').txt 2>&1
Пробовал это мутно на моих Ubuntu vps, но это не сработало. Найти фрагмент онлайн (здесь где-то, что bash и dash работают разные, так что попробовали это:
01 22 * * * "$(command -v bash)" 'source /home/crawler1/env/bin/activate && cd /home/crawler1/project_spiderrooy && scrapy crawl spiderrooy > /home/crawler1/online/flask/static/logs/spiderrooy_log_$(date '+\%Y-\%m-\%d').txt 2>&1'
тоже не работает, попробовал его, не записывая журнал и все еще не работает. Команды вручную do!
sudo grep CRON / var / log / syslog:
Jan 13 12:11:01 crawler2 CRON[2906]: (crawler2) CMD (-v bash)" 'source /home/crawler2/env/bin/activate && cd /home/crawler2/project_spiderahridderkerk && scrapy crawl spiderahridderkerk')
Jan 13 12:11:01 crawler2 CRON[2905]: (CRON) info (No MTA installed, discarding output)
С моими изменениями я никогда не получаю записанный файл журнала или исполняемую команду, даже без log-запись logwrite без даты.
Вопрос: как запустить этот centos cron в ubuntu с датой записи и как остановить No MTA, установленный crap?
Спасибо.
Вы должны запускать все после $(command -v bash) в качестве команды bash (bash -c ...), иначе вся вещь будет рассматриваться как файл (ы), который будет интерпретироваться bash.
Do:
"$(command -v bash)" -c 'source ...'
Итак, в crontab:
01 22 * * * "$(command -v bash)" -c 'source ...'
Вы должны запускать все после $(command -v bash) в качестве команды bash (bash -c ...), иначе вся вещь будет рассматриваться как файл (ы), который будет интерпретироваться bash.
Do:
"$(command -v bash)" -c 'source ...'
Итак, в crontab:
01 22 * * * "$(command -v bash)" -c 'source ...'
Вы должны запускать все после $(command -v bash) в качестве команды bash (bash -c ...), иначе вся вещь будет рассматриваться как файл (ы), который будет интерпретироваться bash.
Do:
"$(command -v bash)" -c 'source ...'
Итак, в crontab:
01 22 * * * "$(command -v bash)" -c 'source ...'
Основная проблема заключается в том, что source - это башизм, что является проблемой в Ubuntu, поскольку оболочка по умолчанию для cron - /bin/sh - и которая разрешает оболочку dash.
] Лучший способ справиться с этим зависит от ряда факторов ИМХО. Исправление, которое вы нашли в другом месте, используя command -v bash для выполнения вашей команды явно с помощью (полностью квалифицированной) оболочки bash, является одним из параметров (хотя, как указано в Bashism , вы пропустили -c до командной строки , на основе записи syslog
Jan 13 12:11:01 crawler2 CRON[2906]: (crawler2) CMD (-v bash)" 'source /home/crawler2/env/bin/activate && cd /home/crawler2/project_spiderahridderkerk && scrapy crawl spiderahridderkerk')
это больше похоже на то, что ваша запись crontab была
01 22 * * * "($command -v bash)" source /home/crawler1/env/bin/activate && cd /home/crawler1/project_spiderrooy && scrapy crawl spiderrooy > /home/crawler1/online/flask/static/logs/spiderrooy_log_$(date '+\%Y-\%m-\%d').txt 2>&1'
такой, что ($command -v bash) расширена до ( -v bash), которая пыталась выполнить [ f13] в подоболочке, а не работает command -v bash внутри подстановки команд).
На практике маловероятно (учитывая довольно ограниченный аргумент по умолчанию cron), что plain bash собирается разрешить что-либо, отличное от $(command -v bash), поэтому IMHO plain bash -c '. . .' или /bin/bash -c '. . .' также будет приемлемый.
В комментариях вы отметили, что ваше собственное решение состоит в том, чтобы добавить SHELL=/bin/bash - лично у меня нет проблем с этим: если вы обеспокоены накладными расходами bash и dash, вы всегда можете ограничить область действия конкретная запись или группа записей, например
# default shell
*/3 * * * * /bin/echo "Job 1 run with \$SHELL=$SHELL" >> $HOME/crontab.log
SHELL=/bin/bash
*/5 * * * * /bin/echo "Job 2 run with \$SHELL=$SHELL" >> $HOME/crontab.log
SHELL=/bin/sh
*/7 * * * * /bin/echo "Job 3 run with \$SHELL=$SHELL" >> $HOME/crontab.log
, приводит к
$ tail -f ~/crontab.log
Job 1 run with $SHELL=/bin/sh
Job 3 run with $SHELL=/bin/sh
Job 2 run with $SHELL=/bin/bash
Job 1 run with $SHELL=/bin/sh
Job 1 run with $SHELL=/bin/sh
Job 2 run with $SHELL=/bin/bash
Job 3 run with $SHELL=/bin/sh
Наконец, если /home/crawler1/env/bin/activate на самом деле является сценарием POSIX (или может быть сделано настолько относительно легко ), а остальные команды в вашем задании - это двоичные исполняемые файлы или скрипты с их собственными действительными строками shebang, тогда вы можете просто изменить команду source на свой эквивалент POSIX ., чтобы все выполнялось в оболочке по умолчанию dash .
Основная проблема заключается в том, что source - это башизм, что является проблемой в Ubuntu, поскольку оболочка по умолчанию для cron - /bin/sh - и которая разрешает оболочку dash.
] Лучший способ справиться с этим зависит от ряда факторов ИМХО. Исправление, которое вы нашли в другом месте, используя command -v bash для выполнения вашей команды явно с помощью (полностью квалифицированной) оболочки bash, является одним из параметров (хотя, как указано в Bashism , вы пропустили -c до командной строки , на основе записи syslog
Jan 13 12:11:01 crawler2 CRON[2906]: (crawler2) CMD (-v bash)" 'source /home/crawler2/env/bin/activate && cd /home/crawler2/project_spiderahridderkerk && scrapy crawl spiderahridderkerk')
это больше похоже на то, что ваша запись crontab была
01 22 * * * "($command -v bash)" source /home/crawler1/env/bin/activate && cd /home/crawler1/project_spiderrooy && scrapy crawl spiderrooy > /home/crawler1/online/flask/static/logs/spiderrooy_log_$(date '+\%Y-\%m-\%d').txt 2>&1'
такой, что ($command -v bash) расширена до ( -v bash), которая пыталась выполнить -v bash в подоболочке, а не работает command -v bash внутри подстановки команд).
На практике маловероятно (учитывая довольно ограниченный аргумент по умолчанию cron), что plain bash собирается разрешить что-либо, отличное от $(command -v bash), поэтому IMHO plain bash -c '. . .' или /bin/bash -c '. . .' также будет приемлемый.
В комментариях вы отметили, что ваше собственное решение состоит в том, чтобы добавить SHELL=/bin/bash - лично у меня нет проблем с этим: если вы обеспокоены накладными расходами bash и dash, вы всегда можете ограничить область действия конкретная запись или группа записей, например
# default shell
*/3 * * * * /bin/echo "Job 1 run with \$SHELL=$SHELL" >> $HOME/crontab.log
SHELL=/bin/bash
*/5 * * * * /bin/echo "Job 2 run with \$SHELL=$SHELL" >> $HOME/crontab.log
SHELL=/bin/sh
*/7 * * * * /bin/echo "Job 3 run with \$SHELL=$SHELL" >> $HOME/crontab.log
, приводит к
$ tail -f ~/crontab.log
Job 1 run with $SHELL=/bin/sh
Job 3 run with $SHELL=/bin/sh
Job 2 run with $SHELL=/bin/bash
Job 1 run with $SHELL=/bin/sh
Job 1 run with $SHELL=/bin/sh
Job 2 run with $SHELL=/bin/bash
Job 3 run with $SHELL=/bin/sh
Наконец, если /home/crawler1/env/bin/activate на самом деле является сценарием POSIX (или может быть сделано настолько относительно легко ), а остальные команды в вашем задании - это двоичные исполняемые файлы или скрипты с их собственными действительными строками shebang, тогда вы можете просто изменить команду source на свой эквивалент POSIX ., чтобы все выполнялось в оболочке по умолчанию dash .
Основная проблема заключается в том, что source - это башизм, что является проблемой в Ubuntu, поскольку оболочка по умолчанию для cron - /bin/sh - и которая разрешает оболочку dash.
] Лучший способ справиться с этим зависит от ряда факторов ИМХО. Исправление, которое вы нашли в другом месте, используя command -v bash для выполнения вашей команды явно с помощью (полностью квалифицированной) оболочки bash, является одним из параметров (хотя, как указано в Bashism , вы пропустили -c до командной строки , на основе записи syslog
Jan 13 12:11:01 crawler2 CRON[2906]: (crawler2) CMD (-v bash)" 'source /home/crawler2/env/bin/activate && cd /home/crawler2/project_spiderahridderkerk && scrapy crawl spiderahridderkerk')
это больше похоже на то, что ваша запись crontab была
01 22 * * * "($command -v bash)" source /home/crawler1/env/bin/activate && cd /home/crawler1/project_spiderrooy && scrapy crawl spiderrooy > /home/crawler1/online/flask/static/logs/spiderrooy_log_$(date '+\%Y-\%m-\%d').txt 2>&1'
такой, что ($command -v bash) расширена до ( -v bash), которая пыталась выполнить -v bash в подоболочке, а не работает command -v bash внутри подстановки команд).
На практике маловероятно (учитывая довольно ограниченный аргумент по умолчанию cron), что plain bash собирается разрешить что-либо, отличное от $(command -v bash), поэтому IMHO plain bash -c '. . .' или /bin/bash -c '. . .' также будет приемлемый.
В комментариях вы отметили, что ваше собственное решение состоит в том, чтобы добавить SHELL=/bin/bash - лично у меня нет проблем с этим: если вы обеспокоены накладными расходами bash и dash, вы всегда можете ограничить область действия конкретная запись или группа записей, например
# default shell
*/3 * * * * /bin/echo "Job 1 run with \$SHELL=$SHELL" >> $HOME/crontab.log
SHELL=/bin/bash
*/5 * * * * /bin/echo "Job 2 run with \$SHELL=$SHELL" >> $HOME/crontab.log
SHELL=/bin/sh
*/7 * * * * /bin/echo "Job 3 run with \$SHELL=$SHELL" >> $HOME/crontab.log
, приводит к
$ tail -f ~/crontab.log
Job 1 run with $SHELL=/bin/sh
Job 3 run with $SHELL=/bin/sh
Job 2 run with $SHELL=/bin/bash
Job 1 run with $SHELL=/bin/sh
Job 1 run with $SHELL=/bin/sh
Job 2 run with $SHELL=/bin/bash
Job 3 run with $SHELL=/bin/sh
Наконец, если /home/crawler1/env/bin/activate на самом деле является сценарием POSIX (или может быть сделано настолько относительно легко ), а остальные команды в вашем задании - это двоичные исполняемые файлы или скрипты с их собственными действительными строками shebang, тогда вы можете просто изменить команду source на свой эквивалент POSIX ., чтобы все выполнялось в оболочке по умолчанию dash .