Как вы можете выполнить скрипт Node.js через задание cron?

Проще говоря, у меня есть скрипт узла, который я хочу выполнять раз в месяц.

30 6 1 * * node /home/steve/example/script.js

Но это не работает, предположительно из-за пути или оболочки, под которой запускается команда. Я пробовал следующие способы выполнения узла через cron (проверено с -v):

steve@atom:~$ node -v
v0.4.2

steve@atom:~$ sh node -v
sh: Can't open node

steve@atom:~$ bash node -v
/usr/local/bin/node: /usr/local/bin/node: cannot execute binary file

steve@atom:~$ /usr/local/bin/node -v
v0.4.2

steve@atom:~$ sh /usr/local/bin/node -v
/usr/local/bin/node: 1: Syntax error: "(" unexpected

steve@atom:~$ bash /usr/local/bin/node -v
/usr/local/bin/node: /usr/local/bin/node: cannot execute binary file

У меня закончились идеи попробовать, какой-нибудь совет?

10 ответов

Решение

Просто укажите полный путь к узлу /usr/local/bin/node в вашей работе cron вроде:

30 6 1 * * /usr/local/bin/node /home/steve/example/script.js

В этих ответах здесь говорится, что использование абсолютного пути вызовет серьезные проблемы для запуска более крупного приложения узла!

Реальное полное решение

Редактировать задания Cron

crontab -e

Найти путь к узлу

which node

CD в ​​папку назначения, затем измените задание Cron в соответствии с путем к узлу и запустите скрипт

*/2 * * * * cd /home/destination/path && /bin/node index.js

Это позволит вам запустить полное приложение NodeJS без всех ошибок, таких как использование абсолютного пути для вашего файла index.js.

Кроме того, просто положить #!/usr/local/bin/node в верхней части скрипта, который вы хотите выполнить. Тогда он автоматически узнает, как выполнить скрипт с узлом. Убедитесь, что файл также является исполняемым.

Вы также можете указать пути к двоичным файлам поверх пользовательского crontab, например:

PATH=/bin:/usr/bin:/usr/local/bin

* * * * * cd your/path && node foo.js
* * * * * cd your/path && npm run bar

В моем ноутбуке с Linux mint указанный путь не работает, поэтому я использовал его, чтобы обойти это.

$ which node

$ /usr/bin/nodeэто сработало для меня.

Это также работает для заданий cron на уровне пользователя.

       */2 * * * * cd /home/destination/path && $(which node) index.js

Пользователи НВМ:

Сохраните следующий скрипт (скажем, cronjob.env.sh) в любом месте вашего PATH (скажем: $HOME/bin). Не забудьте сделать его исполняемым (chmod +x). Также замените «имя пользователя» на ваше имя пользователя:

      #!/bin/bash
export NVM_DIR="/home/username/.nvm"   #replace "username" with your user name
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"  # This loads nvm

Изменить кронджоб:

      crontab -e

Вставьте/отредактируйте свою работу:

      0 0 * * * (. ~/bin/cronjob.env.sh; ~/bin/my-script-with-node-cmd.sh)

Вызов команды узла (вместо какого-либо сценария оболочки), как в приведенном ниже задании, также работает:

      */1 * * * * (. ~/bin/cronjob.env.sh; node ~/index.js)

Пользователи PM2:

Используется другой подходpm2, с--cronвариант, который принимает шаблоны cron (внутри кавычек):

      pm2 start index.js --no-autorestart --cron "0 0 * * *"

--no-autorestartпредназначен для одноразовых скриптов (иначе он будет перезапускаться каждый раз после завершения).

Я не знаю, хорошая ли замена относительных путей в вашем скрипте на абсолютные
(что происходит при изменении вашей файловой системы или при развертывании в другой среде?)

Вы можете попробовать обернуть его в сценарий оболочки, установив некоторые переменные окружения при выполнении crontab. (в частности, PATH & NODE_PATH для начинающих)

Попробуйте мое предложение для этого похожего вопроса:
/questions/16669540/pochemu-cron-ne-vyipolnyaet-moj-skript-nodejs/16669554#16669554

Если вы хотите сохранить функциональность и позволить вашему коду получать обновленную версию узла без необходимости изменять информацию о задании cron, поместите свое задание в сценарий оболочки, который сначала устанавливает nvm, переключается на правильный nodeверсию, а затем запускает фактическую работу. Вот пример проекта под названием invoicingкоторый включает в себя cronсценарий в своем package.json.

Файл invoicing.sh:

      #!/bin/bash
cd /home/produser/invoicing
export NVM_DIR="/home/produser/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
npm run cron

Затем установите это как команду в списке вакансий cron:

      0 16 1 * * produser /home/produser/invoicing/invoicing.sh

Теперь, если вы измените версию узла в своем проекте и обновите .nvmrcс правильным номером версии и загрузите новый код на сервер, при следующем запуске задания cron оно будет выполняться с указанной версией узла. Обратите внимание, что вы также должны убедиться, что сервер имеет требуемую версию узла.

Используйте абсолютные пути для псевдонима узла и файла для запуска.

Редактировать Cron Jobs

crontab -e

Запись для запуска файла нашего узла

Это будет работать каждую минуту.

*/1 * * * * * /bin/node /public/test.js

Полный учебник https://askmacgyver.com/blog/tutorial/how-to-run-node-scripts-from-a-cron-job

Другие вопросы по тегам