繁体   English   中英

Node.js - child_process.exec和输出重定向

[英]Node.js - child_process.exec and output redirection

我正在尝试使用Node.js编写文件模板脚本。 我有一个名为template.json的JSON文件,它存储模板信息。 我的脚本背后的想法是,如果我输入类似的东西:

tmpl.js java Joe

它将执行以下操作:

  1. 打电话给touch Joe.java
  2. 阅读template.json以获取Java文件的模板
  3. 使用其信息用Joe替换所有占位符
  4. 将结果写入Joe.java
  5. 执行emacsclient Joe.java

现在,我写了这个脚本如下:

#!/usr/local/bin/node --harmony

var templates = require('./config/template.json'),
    args = process.argv;

if (args.length < 4) {
    console.log("Not enough arguments!");
} 
else {
    var type = args[2],
        name = args[3];
    if (type in templates) {
        var tmpl = templates[type],
            contents = make_output(tmpl["format"],name),
            file_name = name + tmpl["extension"],
            command = "touch " + file_name + " && echo -e '" + contents +
            "' &> " + file_name + " && emacsclient " + file_name;
        invoke(command);
    }
    else {
        console.log("No template for %s", type);
    }
}


//Helpers

//Invokes comm with args in the terminal, returns all output
//Does not play nice with command redirection
function invoke(comm) {
    var exec = require('child_process').exec,
    child = exec(comm,
             function (error, stdout, stderr) {
                         if (error !== null) {
                 console.log(stderr);
                 }
             });
}

//If template is a format string, processes it with x as the
//replacement. Otherwise, just evaluates.
//Limited to one replacement at most.
function make_output(template, x) {
    if(/.*\%s.*/i.test(template)) {
        var util = require('util');
        return util.format(template,x);
    }
    else {
        return template;
    }
}

基本上,它最终建立的命令是这样的:

touch Joe.java && echo -e `bunch of template stuffs` &> Joe.java && emacsclient Joe.java

现在,我得到的问题是上面的命令依赖于输出重定向,我的invoke命令没有很好地处理 - 具体来说,一切都执行,但我得到一个空文件! 有没有一种方法,我可以改变任何invoke ,否则我什么构造调用,以避免这个问题?

问题是Node的child_process.exec启动了sh但你使用的是bash特有的功能。 &>被解释为& >sh (两个运算符:控制操作员和一个操作者重定向)和echo -e将使用sh的内置执行echo ,其不理解-e

它可能可以解决上面的问题,但像你一样使用shell是脆弱的。 例如,如果您的模板包含单引号( ' ),则这些引号可能会干扰您在命令中使用的单引号。 更强大的方法是更改​​代码的主要部分以使用fs.writeFileSync而不是使用shell命令写入文件:

var templates = require('./config/template.json'),
    fs = require("fs"),
    args = process.argv;

if (args.length < 4) {
    console.log("Not enough arguments!");
}
else {
    var type = args[2],
        name = args[3];
    if (type in templates) {
        var tmpl = templates[type],
            contents = make_output(tmpl["format"],name),
            file_name = name + tmpl["extension"],
            command = "emacsclient " + file_name;

        fs.writeFileSync(file_name, contents);

        invoke(command);
    }
    else {
        console.log("No template for %s", type);
    }
}

您还需要修改make_output以执行echo -e为您完成的转换。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM