如何通过 cron 作业执行 Node.js 脚本?

问题描述 投票:0回答:11

很简单,我有一个节点脚本,我想每月执行一次。

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

但这不起作用,可能是因为运行命令的路径或 shell 的原因。我尝试了以下通过 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

我已经没有办法尝试了,有什么建议吗?

node.js cron
11个回答
131
投票

只需在您的 cron 作业中提供节点

/usr/local/bin/node
的完整路径,例如:

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

62
投票

这里的这些答案说使用绝对路径都会导致运行更大的节点应用程序出现重大问题!

真正完整的解决方案

查找节点路径

which node

编辑 Cron 作业

crontab -e

将 Change Cron Job to CD 设置到目标文件夹中,通过其完整路径调用节点路径并运行脚本

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

这将允许您运行完整的 NodeJS 应用程序,而不会出现所有错误,例如如何为 index.js 文件使用绝对路径。


30
投票

此外,只需将

#!/usr/local/bin/node
放在要执行的脚本的顶部即可。然后它会自动知道用node执行脚本。确保该文件也是可执行的。


13
投票

您还可以在用户 crontab 之上指定二进制文件的路径,例如:

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

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

8
投票

在我使用 Linux mint 的笔记本电脑中,给定的路径不起作用,所以我用它来解决问题。

$ which node

$ /usr/bin/node
这对我有用。


6
投票

这也适用于用户级 cron 作业

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

4
投票

我不知道将脚本中的相对路径更改为绝对路径是否是一个好主意
(当您的文件系统更改或部署在另一个环境中时会发生什么?)

您可以尝试将其包装在 shell 脚本中,在 crontab 执行中设置一些环境变量。 (特别是对于初学者来说

PATH
NODE_PATH

尝试我对这个类似问题的建议:
https://stackoverflow.com/a/27823675/608269


4
投票

NVM 用户:

将以下脚本(例如 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)

调用节点命令(而不是某些 shell 脚本),如下面的作业,也可以工作:

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

PM2用户:

另一种方法是使用

pm2
--cron
选项,它接受 cron 模式(引号内):

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

--no-autorestart
适用于一次性脚本(否则每次完成都会重新启动)。


0
投票

对节点别名和要运行的文件使用绝对路径。

编辑 Cron 作业

crontab -e

运行节点文件的入口

这将每分钟运行一次。

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

完整教程 https://askmacgyver.com/blog/tutorial/how-to-run-node-scripts-from-a-cron-job


0
投票

如果您想保留

nvm
功能并允许您的代码获取更新的节点版本而不需要更改 cron 作业信息,请将您的作业放入首先设置
nvm
的 shell 脚本中,然后切换到正确的
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 作业运行时它将使用指定的节点版本运行。请注意,您还必须确保服务器具有所需的节点版本。


0
投票

对此有一种更简单的解决方案。 虽然有些人可能建议在 cron 文件中使用 node exec 的绝对路径,但您可以只向其添加符号链接 - 它会在 cron 文件中生成更短、更清晰的命令。

  1. 获取节点执行的路径:

哪个节点

此路径可能会有所不同,具体取决于节点使用的安装方法。例如,如果您使用 n 节点版本管理器,则为 /root/n/bin/node。

  1. 复制结果,然后创建符号链接:

ln -s 复制PathFromStepAbove /usr/bin/node

通常 /usr/bin/node 应该位于用于 crons 的路径中。 如果仍然不起作用,您可以通过添加临时 cron 作业来检查用于 cron 的实际 PATH(每分钟执行一次,确保之后将其删除):

crontab -e

添加:

* * * * * echo $PATH >> /root/debug.log

等待 debug.log 文件出现,然后检查路径的内容。

希望有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.