Node 的 spawn() 在从启动时计划的永久脚本中调用时静默失败
Node's spawn() silently failing when called from a forever script scheduled on boot
这有点傻。这个问题很可能与服务器有关,所以我的第一个办法是 AskUbuntu over here。
我正在尝试让 crontab 或 rc.local 或 init.d 在启动时启动 forever 脚本。它将一个服务器连接到一个端口,我可以用一些信息 ping 并让它 运行 对我来说是一个无头浏览器。
也就是说,我似乎无法从 Node.js 的 spawn()
:
那里得到回复
var CASPER_PATH = '/home/ubuntu/dev/casperjs/bin/casperjs'; // actual binary location, not a symlink
var SCRIPTS_PATH = '/home/custom_user/endpoints/server.js';
var fileName = req.body.source + '_' + req.body.type + '.coffee'; // looks like: mysource_my_scrape_type.coffee
var scrapeId = 'test_scrape';
var user = 'user123';
var pass = 'pass123';
if (fs.existsSync(SCRIPTS_PATH + fileName)) {
// If file is in place, spawn casperjs
var sP = spawn(CASPER_PATH,
[SCRIPTS_PATH + fileName, '--ssl-protocol=any', '--user='+user, '--scrapeId='+scrapeId, '--pass='+pass],
{ detached: true },
function (err, stdout, stderr) {});
sP.stdout.on('data', function(data) { console.log('stdout', data.toString('utf8')); });
sP.stderr.on('data', function(data) { console.log('stderr', data.toString('utf8')); });
sP.stdout.on('close', function(code) { console.log('close', code); });
res.send({ scheduled: true, key: scrapeId });
} else {
res.send({ scheduled: false, error: 'Incorrect source, type or the script is missing.' });
}
在我将 PHANTOMJS_EXECUTABLE
env 添加到 crontab
或 rc.local
之前(无论用户级别如何,似乎都不重要),stdout 很有用:
stdout Fatal: [Errno 2] No such file or directory; did you install
phantomjs?
close false
既然有了环境变量,spawn()
之后就完全没有输出了。
请注意,如果来自 bash.
的 运行s node/forever 用户(任何权限级别),Casper 启动都很好
我如何知道 spawn()
失败的原因?
我没有完全理解你的要求。但是我在 Ubuntu 无头服务器上也有类似的情况。
我想在这里做的就是我所做的
首先,我的 crontab 怎么样?
crontab -u USER -e
@reboot exec sudo -u USER /bin/bash /home/USER/SHELL_SCRIPT.sh
看,我实际上是在启动一个 shell 脚本,而不是节点服务器
现在在这个 shell 脚本中(SHELL_SCRIPT.sh)
#! /bin/bash
# SHELL_SCRIPT.sh
cd /home/USER/
/home/USER/.npm-packages/bin/forever start -p /home/USER -a -d --watch false --pidFile /home/USER/forever.pid -l /home/USER/forever.log -o /home/USER/forever.out -e /home/USER/forever.err /home/USER/MY_NODE.js
甚至在我的 MY_NODE.js 中我遵循绝对路径,我只是忽略 $PATH,并且不使用它。
在此节点服务器内,我进行了 100 次生成
现在,我大约 2 年前就这样做了,所以如果你问我为什么这样做,我无法回答
这实际上看起来像是 forever、spawn 和 casperjs(可能是 phantomjs)之间的组合错误。
我能够重现您的问题,here is 我的测试应用程序的完整代码。
你没有显示完整的代码,所以我猜你有一个快速应用程序,并且有一个特殊的 URL 到 运行 casperjs 脚本。
我构建了一个像这样的简单应用程序,它的行为是这样的:
- 只需使用
node script.js
启动应用程序(script.js
是 运行s server.js
中的 casperjs 脚本的快速应用程序)- 它工作正常,呈现响应并写入从子进程事件处理程序输出到控制台
- 使用 init.d 脚本以 root 身份启动应用程序 - 不起作用,一旦生成子项,就不会触发任何事件处理程序
- 使用 init.d 脚本以 root 身份启动应用程序,将 casperjs 替换为
echo
- 同样,不起作用(看,这里只有 forever
运行ning 作为 root,spawn
和 echo
)
- 使用 init.d 以普通用户(非 root)身份启动应用程序,将 casperjs 替换为 'echo' - 它有效,事件处理程序被触发,在这里我几乎可以肯定问题已解决,但是... :(
- 使用 init.d 以普通用户(非 root)身份启动应用程序,放回 casperjs - 它不再工作,事件处理程序未被触发
使用 pm2 的实用解决方案,我这样做了:
# install pm2
sudo npm install -g pm2
# generate init.d scripts for pm2
# this command will fail, but hint about the correct format with sudo
pm2 startup ubuntu
# do this in the folder with your application
pm2 start script.js
# remember your application
pm2 save
# also useful
# sudo service stop/start/restart pm2
# pm2 stop/start/restart script
现在 pm2
将随系统自动启动并启动您的应用程序。一切正常,子进程事件处理程序被触发。
这有点傻。这个问题很可能与服务器有关,所以我的第一个办法是 AskUbuntu over here。
我正在尝试让 crontab 或 rc.local 或 init.d 在启动时启动 forever 脚本。它将一个服务器连接到一个端口,我可以用一些信息 ping 并让它 运行 对我来说是一个无头浏览器。
也就是说,我似乎无法从 Node.js 的 spawn()
:
var CASPER_PATH = '/home/ubuntu/dev/casperjs/bin/casperjs'; // actual binary location, not a symlink
var SCRIPTS_PATH = '/home/custom_user/endpoints/server.js';
var fileName = req.body.source + '_' + req.body.type + '.coffee'; // looks like: mysource_my_scrape_type.coffee
var scrapeId = 'test_scrape';
var user = 'user123';
var pass = 'pass123';
if (fs.existsSync(SCRIPTS_PATH + fileName)) {
// If file is in place, spawn casperjs
var sP = spawn(CASPER_PATH,
[SCRIPTS_PATH + fileName, '--ssl-protocol=any', '--user='+user, '--scrapeId='+scrapeId, '--pass='+pass],
{ detached: true },
function (err, stdout, stderr) {});
sP.stdout.on('data', function(data) { console.log('stdout', data.toString('utf8')); });
sP.stderr.on('data', function(data) { console.log('stderr', data.toString('utf8')); });
sP.stdout.on('close', function(code) { console.log('close', code); });
res.send({ scheduled: true, key: scrapeId });
} else {
res.send({ scheduled: false, error: 'Incorrect source, type or the script is missing.' });
}
在我将 PHANTOMJS_EXECUTABLE
env 添加到 crontab
或 rc.local
之前(无论用户级别如何,似乎都不重要),stdout 很有用:
stdout Fatal: [Errno 2] No such file or directory; did you install phantomjs?
close false
既然有了环境变量,spawn()
之后就完全没有输出了。
请注意,如果来自 bash.
的 运行s node/forever 用户(任何权限级别),Casper 启动都很好我如何知道 spawn()
失败的原因?
我没有完全理解你的要求。但是我在 Ubuntu 无头服务器上也有类似的情况。
我想在这里做的就是我所做的
首先,我的 crontab 怎么样?
crontab -u USER -e
@reboot exec sudo -u USER /bin/bash /home/USER/SHELL_SCRIPT.sh
看,我实际上是在启动一个 shell 脚本,而不是节点服务器
现在在这个 shell 脚本中(SHELL_SCRIPT.sh)
#! /bin/bash
# SHELL_SCRIPT.sh
cd /home/USER/
/home/USER/.npm-packages/bin/forever start -p /home/USER -a -d --watch false --pidFile /home/USER/forever.pid -l /home/USER/forever.log -o /home/USER/forever.out -e /home/USER/forever.err /home/USER/MY_NODE.js
甚至在我的 MY_NODE.js 中我遵循绝对路径,我只是忽略 $PATH,并且不使用它。
在此节点服务器内,我进行了 100 次生成
现在,我大约 2 年前就这样做了,所以如果你问我为什么这样做,我无法回答
这实际上看起来像是 forever、spawn 和 casperjs(可能是 phantomjs)之间的组合错误。 我能够重现您的问题,here is 我的测试应用程序的完整代码。
你没有显示完整的代码,所以我猜你有一个快速应用程序,并且有一个特殊的 URL 到 运行 casperjs 脚本。
我构建了一个像这样的简单应用程序,它的行为是这样的:
- 只需使用
node script.js
启动应用程序(script.js
是 运行sserver.js
中的 casperjs 脚本的快速应用程序)- 它工作正常,呈现响应并写入从子进程事件处理程序输出到控制台 - 使用 init.d 脚本以 root 身份启动应用程序 - 不起作用,一旦生成子项,就不会触发任何事件处理程序
- 使用 init.d 脚本以 root 身份启动应用程序,将 casperjs 替换为
echo
- 同样,不起作用(看,这里只有forever
运行ning 作为 root,spawn
和echo
) - 使用 init.d 以普通用户(非 root)身份启动应用程序,将 casperjs 替换为 'echo' - 它有效,事件处理程序被触发,在这里我几乎可以肯定问题已解决,但是... :(
- 使用 init.d 以普通用户(非 root)身份启动应用程序,放回 casperjs - 它不再工作,事件处理程序未被触发
使用 pm2 的实用解决方案,我这样做了:
# install pm2
sudo npm install -g pm2
# generate init.d scripts for pm2
# this command will fail, but hint about the correct format with sudo
pm2 startup ubuntu
# do this in the folder with your application
pm2 start script.js
# remember your application
pm2 save
# also useful
# sudo service stop/start/restart pm2
# pm2 stop/start/restart script
现在 pm2
将随系统自动启动并启动您的应用程序。一切正常,子进程事件处理程序被触发。