当从在引导时调度的永久脚本调用时,节点的spawn()以静默方式失败

dsp*_*099 5 javascript linux node.js phantomjs casperjs

这有点儿麻烦.这个问题很可能与服务器有关,因此我的第一个问题是AskUbuntu.

我正在尝试使用crontab或rc.local或init.d来启动永久脚本.它将服务器连接到一个端口,我可以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.' });
}
Run Code Online (Sandbox Code Playgroud)

在我添加PHANTOMJS_EXECUTABLEenv 之前crontabrc.local(无论用户级别似乎无关紧要)之前,stdout很有用:

stdout致命:[Errno 2]没有这样的文件或目录; 你安装了phantomjs吗?

关闭错误

既然环境变量存在,那么之后就没有输出了spawn().

请注意,如果用户(任何权限级别)从bash运行节点/永远,Casper就会启动.

我怎么知道为什么spawn()会失败?

Bor*_*rov 2

这实际上看起来像是forever、spawn 和casperjs(也许是phantomjs)之间的组合bug。我能够重现您的问题,这是我的测试应用程序的完整代码。

您没有显示完整的代码,所以我的猜测是您有一个 Express 应用程序,并且有一个特殊的 URL 来运行 casperjs 脚本。

我构建了一个像这样的简单应用程序,它的行为方式如下:

  • 只需使用node script.jsscript.js是运行 casperjs 脚本的快速应用程序server.js)启动应用程序 - 它工作正常,呈现响应并将子进程事件处理程序的输出写入控制台
  • 使用 init.d 脚本以 root 身份启动应用程序 - 不起作用,一旦生成子进程,就不会触发任何事件处理程序
  • 使用 init.d 脚本以 root 身份启动应用程序,将 casperjs 替换为echo- 相同,但不起作用(请参阅,这里我们仅以foreverroot 身份运行时遇到此问题,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
Run Code Online (Sandbox Code Playgroud)

现在pm2系统将自动启动并启动您的应用程序。一切正常,子进程事件处理程序被触发。