我有一个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();
答案 0 :(得分:5)
来自end
的{{1}}事件检测到空的或没有STDIN流。
这个简单的脚本process.stdin
证明了:
stdin.js
不同的情景:
process.stdin.on( 'data', function(data) { console.log( data ) } );
process.stdin.on( 'end', function() { console.log( 'EOF' ) } );
此脚本$ echo test | node stdin.js
<Buffer 74 65 73 74 0a>
EOF
$ echo -n | node stdin.js
EOF
$ node stdin.js < /dev/null
EOF
$
表明使用管道生成的子进程非常有效:
pipe.js
正如所料:
var spawn = require('child_process').spawn;
var cat = spawn( '/bin/cat' );
cat.stdout.on( 'data', function(data) { console.log( data ) } );
cat.stdout.on( 'end', function() { console.log( 'EOF' ) } );
process.stdin.pipe(cat.stdin);
答案 1 :(得分:5)
我相信可能发生的事情是,你根本没有给出斯坦丁。
ØysteinSteimler的示例显示您将 / dev / null 提供给您的应用:
node pipe.js&lt;的/ dev / null的
但是,当你根本没有将stdin流式传输到应用程序时,永远不会解决。只运行node pipe.js
不会退出,因为它仍在等待 stdin 。
您可以使用其他unix程序自行测试,例如cat
尝试运行:
cat < /dev/null
现在尝试运行:
cat
它不会退出,因为它正在等待stdin。您可以输入终端并按Enter键发送到程序。它仍然不会退出(并等待更多输入),直到它收到 EOF ,您可以使用 ctrl + d
答案 2 :(得分:2)
你可以做的就是让你的应用程序接受-s
这样的参数,使其从标准输入读取。
这就是LiveScript的CLI工具:
-s, --stdin read stdin
答案 3 :(得分:1)
stdin
的工作方式无法直接实现。
正如其他人指出的那样,如果没有end
之类的东西来生成 EOF ,< /dev/null
事件将永远不会触发。否则,程序将等待终端发送^D
。
对您可能有用的另一种方法是,如果stdin
上没有任何活动,则设置一个超时时间,该超时时间将在短时间内到期。这不理想,但是可以工作:
function handleData(chunk) {
//clearTimeout(timeout);
gfm.stdin.write(chunk);
}
function handleEnd() {
//clearTimeout(timeout);
gfm.stdin.end();
}
function handleTimeout() {
process.stdin.removeListener('data', handleData);
process.stdin.removeListener('end', handleEnd);
// Do whatever special handling is needed here.
gfm.stdin.end();
}
const timeoutMilliseconds = 100;
process.stdin.on('data', handleData);
process.stdin.on('end', handleEnd);
const timeout = setTimeout(handleTimeout, timeoutMilliseconds);
// You could skip the rest of this code if you just add `clearTimeout(timeout)`
// to the body of `handleData` and `handleEnd` but that would call `clearTimeout` excessively.
function stopTimeout() {
process.stdin.removeListener('data', stopTimeout)
process.stdin.removeListener('end', stopTimeout);
clearTimeout(timeout);
}
process.stdin.on('data', stopTimeout);
process.stdin.on('end', stopTimeout);