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

Javascript Node.js-child_process.exec和输出重定向,javascript,json,node.js,Javascript,Json,Node.js,我正在尝试使用Node.js编写一个文件模板脚本。我有一个名为template.JSON的JSON文件,它存储模板信息。我的脚本背后的想法是,如果我键入以下内容: tmpl.js java Joe touch Joe.java && echo -e `bunch of template stuffs` &> Joe.java && emacsclient Joe.java 它将执行以下操作: 调用touch Joe.java 阅读template

我正在尝试使用Node.js编写一个文件模板脚本。我有一个名为
template.JSON
的JSON文件,它存储模板信息。我的脚本背后的想法是,如果我键入以下内容:

tmpl.js java Joe
touch Joe.java && echo -e `bunch of template stuffs` &> Joe.java && emacsclient Joe.java
它将执行以下操作:

  • 调用
    touch Joe.java
  • 阅读
    template.json
    以获取Java文件的模板
  • 使用其信息将所有占位符替换为
    Joe
  • 将结果写入
    Joe.java
  • 执行
    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;
        }
    }
    

    现在,我遇到的问题是,上面的命令依赖于输出重定向,我的
    invoke
    命令不能很好地处理这一问题-具体地说,所有操作都会执行,但我得到一个空文件!是否有一种方法可以更改
    invoke
    或我正在构造的调用对象以避免此问题?

    问题在于节点的
    子进程。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);
        }
    }
    
    var templates=require('./config/template.json'),
    fs=要求(“fs”),
    args=process.argv;
    如果(参数长度<4){
    log(“参数不足!”);
    }
    否则{
    变量类型=args[2],
    name=args[3];
    如果(键入模板){
    var tmpl=模板[类型],
    内容=生成输出(tmpl[“格式”],名称),
    file_name=name+tmpl[“扩展名”],
    command=“EmacClient”+文件名;
    fs.writeFileSync(文件名、内容);
    调用(命令);
    }
    否则{
    console.log(“没有%s的模板”,类型);
    }
    }
    
    您还需要修改
    make_output
    ,以执行
    echo-e
    将为您完成的转换