Как вы можете выполнить скрипт 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