从启动时计划的永远脚本调用节点的spawn()时,会自动失败

这是一个很愚蠢的。 这个问题是最有可能的服务器相关,所以我的第一个求助是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.' }); } 

在将PHANTOMJS_EXECUTABLE env添加到crontabrc.local (不pipe用户级别似乎都不重要),stdout非常有用:

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

closures错误

现在环境var在那里,在spawn()之后根本没有输出。

请注意,如果用户(任何特权级别)从bash永远运行节点,Casper启动就好了。

我怎么看到为什么spawn()失败?

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

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

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

  • 刚开始使用node script.jsscript.js是在server.js运行casperjs脚本的快速应用程序)的应用程序 – 它工作正常,呈现响应并将输出从子进程事件处理程序写入到控制台
  • 使用init.d脚本以root用户身份启动应用程序 – 不起作用,一旦生成子代,就不会触发事件处理程序
  • 用init.d脚本启动应用程序,使用echo替换casperjs – 相同,不起作用(请参阅,这里我们有这个问题,只是forever以root身份运行, spawnecho
  • 启动应用程序作为一个普通的用户(不是根)与init.d,用'echo'代替casperjs – 它的工作原理,触发事件处理程序,在这里我几乎可以肯定问题已经解决,但… 🙁
  • 启动应用程序作为普通用户(不是根)与init.d,放回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会自动启动系统,它会启动您的应用程序。 一切正常,触发子进程事件处理程序。

我完全不了解你的要求。 但是我也有类似的情况与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年左右的时间里做了这个,所以如果你问我为什么这样做,我不能回答