[英]Node.js - child_process.exec and output redirection
I'm trying to write a file templating script using Node.js. 我正在尝试使用Node.js编写文件模板脚本。 I have a JSON file called
template.json
which stores template information. 我有一个名为
template.json
的JSON文件,它存储模板信息。 The idea behind my script is that, if I type something like: 我的脚本背后的想法是,如果我输入类似的东西:
tmpl.js java Joe
it will do the following: 它将执行以下操作:
touch Joe.java
touch Joe.java
template.json
to get the template for Java files template.json
以获取Java文件的模板 Joe
Joe
替换所有占位符 Joe.java
Joe.java
emacsclient Joe.java
emacsclient Joe.java
Now, I wrote this script as follows: 现在,我写了这个脚本如下:
#!/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;
}
}
Basically, the command it ends up building is something like: 基本上,它最终建立的命令是这样的:
touch Joe.java && echo -e `bunch of template stuffs` &> Joe.java && emacsclient Joe.java
Now, the problem I am getting is that the above command relies on output redirection, which my invoke
command doesn't deal with very well - specifically, everything executes, but I get an empty file! 现在,我得到的问题是上面的命令依赖于输出重定向,我的
invoke
命令没有很好地处理 - 具体来说,一切都执行,但我得到一个空文件! Is there a way I can change either invoke
or what I'm constructing to be invoked to avoid this problem? 有没有一种方法,我可以改变任何
invoke
,否则我什么构造被调用,以避免这个问题?
The issue is that Node's child_process.exec
starts sh
but you are using features that are peculiar to bash
. 问题是Node的
child_process.exec
启动了sh
但你使用的是bash
特有的功能。 The &>
is interpreted as & >
in sh
(two operators: a control operator and a redirection operator) and echo -e
will use sh
's builtin implementation of echo
, which does not understand -e
. 的
&>
被解释为& >
在sh
(两个运算符:控制操作员和一个操作者重定向)和echo -e
将使用sh
的内置执行echo
,其不理解-e
。
It would probably be possible to work around the issues above but using the shell like you do is fragile. 它可能可以解决上面的问题,但像你一样使用shell是脆弱的。 For instance if your template contains single quotes (
'
), these quotes may interfere with the single quotes you use in your command. 例如,如果您的模板包含单引号(
'
),则这些引号可能会干扰您在命令中使用的单引号。 A more robust way to do it would be to change the main part of your code to use fs.writeFileSync
rather than using shell commands to write to your file: 更强大的方法是更改代码的主要部分以使用
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);
}
}
You'd also want to modify make_output
to perform the transformations that echo -e
would have done for you. 您还需要修改
make_output
以执行echo -e
为您完成的转换。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.