如何在node.js中处理标准输出流(stdout)

3
我正在尝试自动化我每次在服务器上测试应用和网站时要进行的过程。我目前在nodejitsu上运行。当我在本地机器上测试了某些东西并且它能正常工作时,下一步是...
  1. 打开我的package.json文件
  2. 删除domains字段,并将名称和子域更改为staging。(可能还有更改版本号的意义)
  3. 然后我执行
  4. 确认任何提示(例如批准版本号的增量)
  5. 一旦应用程序启动,我会检查我的应用程序在服务器上的运行情况,进行更改等操作
完成后,如果我的应用程序已经准备好,我会撤消对package.json文件的更改。我想自动化这个过程。我考虑使用一个小的node.js文件来实现。到目前为止,它是这样的...
/*
 * Use this file to deploy an app to the staging server on nodejitsu
 */
var bash = require('child_process').spawn('bash');
var colors = require('colors');
var fs = require('fs');

// stdout setup
bash.stdout.on('data', function (data) {
  console.log('stdout: ' + data);
});
bash.stdout.on('error', function (err) {
  console.log('stdout error: '.red, err);
});

// on bash exit
bash.on('exit', function (code) {
  console.log('Exiting... ', code);
});

// grab package.json
var package = '';
fs.readFile('package.json', {encoding: 'utf-8'}, function (err, data) { // grab the package.json file contents
  if (err) throw err;
  package = JSON.parse(data);
  fs.rename('package.json', 'rename-me-before-deploying.json'); // rename the package.json file
  package.name = 'stajing'; // alter json
  package.subdomain = 'stajing'; // alter json
  package.domains = []; // alter json
  fs.writeFile('package.json', JSON.stringify(package, null, 2), function(err) { // write the new package to package.json
    if (err) throw err;
    bash.stdin.write('jitsu deploy\n'); // Deploy to staging app on nodejitsu.
    setTimeout(function () { // this needs to be replaced
      bash.stdin.write('yes\n');
    }, 5000);
    console.log("All done : )");
    // bash.stdin.end(); // close out
  });
});

我这里有几个问题。我相信为了完成它,我需要知道的是当Nodejitsu提示我递增版本号时触发的事件prompt: Is this ok?: (yes),以便我可以确认,如果发生了这种情况,以及整个过程完成时触发的事件,以便我可以还原对package.json文件的更改,使我的应用程序部署到暂存环境并且我的文件本质上没有受到影响。


2
undefined 似乎来自于 'exit' 事件,因为 colors 似乎没有定义 orange - Jonathan Lonowski
你太棒了!!!!!(感叹号是 Stackoverflow 评论的最小字符数) - Costa Michailidis
2
你的问题是什么?顺便问一下,为什么你要操纵你的package.json文件?你不应该这样做。有不同的可能性来处理特定环境的配置。 - greelgorke
我最终发了另一个问题(在这里:https://dev59.com/uX7aa4cB1Zd3GeqPwvDr),最终我需要做这个:https://gist.github.com/CostaMichailidis/11181252 - Costa Michailidis
我同意你不应该需要操作package.json文件,但是我找不到其他测试我的应用程序在服务器上的方法,因为它将用于生产环境。我可以在本地进行测试,但一旦部署,它就会上线(至少据我所知,与NODE_ENV无关)。因此,我设置了一个单独的“应用程序”,并使用一个单独的无人机来测试我的网站/应用程序。 - Costa Michailidis
显示剩余2条评论
1个回答

2

我这里没有设置来运行jitsu deploy。不过,以下代码说明了如何处理提示:

var command = require('child_process').spawn('./command.js');
require('colors');

var stdout = "";
var prompt_re = /Is it okay \(yes\)\?.*?$/m;
command.stdout.on('data', function (data) {
    console.log("stdout data: ".green + data);
    stdout += data;
    if (prompt_re.test(stdout)) {
        command.stdin.write("yes\n");
        // Flush the current buffer.
        stdout = "";
    }
});

command.stdout.on('error', function (err) {
    console.log('stdout error: '.red, err);
});

var exit_msg = 'Exited with code... ';
command.on('exit', function (code) {
    if (code != 0) {
        console.log(exit_msg.red, code);
        process.exit(1); // Or whatever you want to handle errors.
    }

    console.log(exit_msg.green, code);
    // The code you want to execute once your command is done goes here.
});

一些解释:

  1. 上面的代码从command.stdout获取数据并将其缓冲到存储在stdout变量中的字符串中,然后针对该字符串进行测试,因为如果有大量输出,则不能保证提示符会在单个data事件中到达。 (例如,它可能在一个包含大量数据+字符串Is it的事件中到达,然后下一个data事件可能包含其余的提示符。)

  2. 正则表达式prompt_re包含“.*?$”,因为我用于模拟获得提示符的命令使用颜色的转义代码,而我无法匹配输出的确切代码。

  3. 此代码假定命令在输出提示符后立即停止并等待。这似乎是一个安全的假设。

  4. 它还假定提示文本不能出现为非提示符的内容。这是否安全取决于您的具体情况。

我用来模拟运行命令的./command.js文件是:

#!/usr/bin/env node

var prompt = require("prompt");

function ask(cb) {
    prompt.get(["Is it okay (yes)?"], function (err, result) {
        console.log("asked");
        cb();
    });
}

setTimeout(function () {
    ask(function () {
        setTimeout(function () {
            ask(function () { process.exit(0); });
        }, 1000);
    });
}, 5000);

它等待5秒钟,提示一次,等待1秒钟,再提示一次,然后退出。

感谢Louis的帮助,这是我最终做的事情:https://gist.github.com/CostaMichailidis/11181252 - Costa Michailidis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接