如何从shell脚本中检测其标准输出是否被发送到终端或者是否通过管道传输到另一个进程?
举个例子:我想添加转义代码来着色输出,但只有在交互式运行时,而不是在管道输出时,类似于什么ls --color.
我看到如何使用Node.js流将各种东西连接在一起,但是如何使用Unix将多个脚本连接在一起|,因为其中一些脚本可以是异步的?
$ ./a.js | ./b.js
Run Code Online (Sandbox Code Playgroud)
例:
a.js(chmod 0755)
#!/usr/bin/env node
setTimeout(function(){
console.log(JSON.stringify({ foo: 'bar' }));
}, 10);
Run Code Online (Sandbox Code Playgroud)
b.js(chmod 0755)
#!/usr/bin/env node
console.log(process.argv);
Run Code Online (Sandbox Code Playgroud)
这是输出:
$ ./a.js | ./b.js
[ 'node', '/Users/viatropos/tests/b.js' ]
events.js:72
throw er; // Unhandled 'error' event
^
Error: write EPIPE
at errnoException (net.js:883:11)
at Object.afterWrite (net.js:700:19)
Run Code Online (Sandbox Code Playgroud)
乍一看似乎有很多问题,所以不确定从哪里开始.有没有办法让这个工作?最终目标是能够从中获取console.log输出./a.js并将其用于./b.js.原因是,大多数情况下这些脚本将一次运行一个,但有时将它们组合在一起会很好,所以理想情况下系统应该能够处理这两种情况.
在RingoJS中有一个叫做的函数read,它允许你读取整个流,直到到达终点.这在您创建命令行应用程序时很有用.例如,您可以编写如下tac 程序:
#!/usr/bin/env ringo
var string = system.stdin.read(); // read the entire input stream
var lines = string.split("\n"); // split the lines
lines.reverse(); // reverse the lines
var reversed = lines.join("\n"); // join the reversed lines
system.stdout.write(reversed); // write the reversed lines
Run Code Online (Sandbox Code Playgroud)
这允许您启动shell并运行tac命令.然后根据需要输入任意数量的行,完成后可以按Ctrl+ D(或Windows上的Ctrl+ Z)表示传输结束.
我想在node.js中做同样的事情,但我找不到任何会这样做的函数.我想用的readSync 功能,从fs图书馆到模拟如下,但无济于事:
fs.readSync(0, buffer, 0, buffer.length, null);
Run Code Online (Sandbox Code Playgroud)
在对标准输入文件描述符(第一个参数)是0.所以它应该从键盘读取数据.相反,它给了我以下错误:
Error: ESPIPE, invalid seek …Run Code Online (Sandbox Code Playgroud) 我有一个node.js脚本/服务器,它在启动时读取stdin的一些输入.但是,有时候没有数据要传入.这很麻烦,因为在这种情况下似乎既不调用data也不end调用事件.如何在node.js代码中检测到这种情况?
我想避免在输入结束时附加特殊的"结束"字符,以免给客户带来不便.相关代码如下:
var newHTML = '';
var gfm = spawn(__dirname + '/node_modules/docter/bin/github-flavored-markdown.rb');
process.stdin.on('data', function(chunk){
gfm.stdin.write(chunk);
});
process.stdin.on('end', function(){
gfm.stdin.end();
});
gfm.stdout.on('data', function(data) {
newHTML += data;
});
gfm.on('exit',function(ecode){
socket.emit('newContent', newHTML);
});
process.stdin.resume();
Run Code Online (Sandbox Code Playgroud) 我正在编写 clojure cli,想知道是否有办法测试输出(即 println)是写入控制台还是通过管道传输到另一个程序?
这与this question类似,但对于clojure。