# index.js
console.log(process.argv) // expect this to print [.., .., '1']
# terminal
$ echo 1 | node index.js // just prints [.., ..]
诀窍是什么?如何通过echo
,ls
,ps aux
等unix命令从命令行动态地将参数传递给节点脚本?
注意:我看到我可以使用stdin
在我的脚本中读取中的unix命令的输出,但我喜欢的是真正传递参数从命令行脚本。
答案 0 :(得分:1)
$ echo 1 | node index.js
在此命令中echo
将1
打印到标准输出redirected(通过管道)到node
命令的标准输入,该命令接受index.js
参数。如果要读取echo
打印的字符串,请阅读标准输入,例如:
var text = '';
process.stdin.setEncoding('utf8');
process.stdin.on('readable', function () {
var chunk = process.stdin.read();
if (chunk !== null) {
text += chunk;
}
});
process.stdin.on('end', function () {
console.log(text);
});
如何通过unix命令(如echo,ls,ps aux等)从命令行动态地将参数传递给节点脚本。?
使用管道,您只能重定向命令的批量输出。您可以使用command substitution将多个命令的输出作为字符串传递,例如:
node index.js --arg1="$(ls -ld /tmp)" --arg2="$(stat -c%a /tmp)"
将命令的输出分配给shell变量,以使脚本更具可读性:
arg1="$(ls -ld /tmp)"
node index.js --arg1="$arg1"
答案 1 :(得分:0)
我的一位朋友向我展示了这一点:
$ node index.js `echo 1 2 3 4`
实际上正是我想要的。这将导致:
// index.js
process.argv // [.., .., '1', '2', '3', '4']
这和@RuslanOsmanov答案的区别在于上面的内容会将输出作为节点进程的所有参数传递,而:
$ node --arg1=`echo 1` --arg2=`echo 2`
每个参数都需要一个单独的命令。
如果您的文件名包含空格,则ls
将无法正常工作,因为空格字符被视为参数分隔符。
有关使用后退标记的更多信息,请参阅What does the backtick - ` - do in a command line invocation specifically with regards to Git commands?。
答案 2 :(得分:0)
每次调用 console.log()
时,您一直在隐式使用 process.stdout 可写流。在内部,console.log()
函数在格式化输入参数后调用 process.stdout.write()
。但控制台功能更多用于调试和检查对象。当需要将结构化数据写入stdout时,可以直接调用process.stdout.write()
。
假设您的程序连接到一个 HTTP URL 并将响应写入标准输出。 Stream#pipe()
在这种情况下效果很好,如下所示:
var http = require('http');
var url = require('url');
var target = url.parse(process.argv[2]);
var req = http.get(target, function (res) {
res.pipe(process.stdout);
});
在从 stdin 读取数据之前,您必须调用 process.stdin.resume()
以表明您的脚本对来自 stdin 的数据感兴趣。之后,stdin 就像任何其他可读流一样,在从另一个进程的输出接收到数据时,或在用户在终端窗口中输入按键时发出数据事件。
以下清单显示了一个命令行程序,该程序在决定是否继续执行之前会提示用户输入年龄。
为了改进@Joseph 的回答,您可以在反引号之间使用这两个命令() and
$(enter code here)` :
$ node --arg1=`echo 1` --arg2=$(echo 2)