如何在 Node 中关闭标准输入?
How do I close stdin in Node?
我正在学习 Node.js 并认为我有一个非常简单的脚本,但任何调整都不会使我的脚本永远挂起。
假设我有一个哑服务器 运行ning:
$ nc -l 32001 <<EOF
HTTP/1.1 200 OK
Content-Type: text/plain
Works
EOF
我运行以下脚本:
var http = require('http');
var options = {
hostname: 'localhost',
port: 32001,
method: 'POST',
headers: {'Content-Type': 'text/plain'}
};
var req = http.request(options, res => {
var exitCode = res.statusCode >= 200 && res.statusCode < 300 ? 0 : 1;
res.pipe(process.stdout).on('end', () => process.exit(exitCode));
});
req.on('error', error => console.error(error));
process.stdin.pipe(req)
.on('end', () => console.log('this does trigger'));
但是当我执行以下操作时:
$ echo foobar | node my-script.js
它只是挂起,永远不会到达请求回调。我希望请求流结束并调用 http.request 回调,然后输出 Works
并最终退出进程。
我检查过 end
事件确实是从 process.stdin.pipe()
调用的,并且我试图在 end
回调中手动结束 req
流。但它不会结束。如何将标准输入通过管道传输到 http.request 并仍然让它结束流?
你走在正确的轨道上;您只需要将您的侦听器附加到适当的对象事件。在第一种情况下(书面的,而不是执行的):
res.pipe(process.stdout).on('end', () => process.exit(exitCode));
你说的:"Pipe the data from response to stdout, and when stdout ends, exit the process."
你的意思:"Pipe the data from response to stdout. When response ends, exit the process." 编码:
res.pipe(process.stdout);
res.on('end', () => process.exit(exitCode));
这里需要明确的一点是,除非您明确关闭 process.stdout
,否则它将 永远不会 close/end 直到您退出该程序。然而,response
将在 HTTP 交互完成时结束。
第二种情况类似:
process.stdin.pipe(req)
.on('end', () => console.log('this does trigger'));
你说的:"Pipe the data from stdin to request, and when request ends, write a message."
你的意思:"Pipe the data from stdin to request. When stdin ends, write a message." 编码:
process.stdin.pipe(req);
process.stdin.on('end', () => console.log('this does trigger'));
这里稍微有些细微差别,因为您可以监听 stdin 的 end
事件或 request 的事件finish
事件:
process.stdin.pipe(req).on('finish', () => console.log('Request has finished writing/sending');
process.stdin.on('end', () => console.log('Stdin has no more data'));
那么,为了完整起见,您的工作客户会回复您,为了假设的教学清晰度,对文本进行了一些轻微的修改:
var http = require('http');
var options = {
hostname: 'localhost',
port: 32001,
method: 'POST',
headers: {'Content-Type': 'text/plain'}
};
var req = http.request(options, res => {
var exitCode = res.statusCode >= 200 && res.statusCode < 300 ? 0 : 1;
res.pipe(process.stdout);
res.on('end', () => {
console.log('Response (IncomingMessage) has no more data; exiting with code:', exitCode);
process.exit(exitCode);
});
});
req.on('error', error => console.error(error));
process.stdin.on('end', () => console.log('Stdin has no more data.'));
process.stdin.pipe(req).on('finish', () => console.log('Request has finished writing/sending'));
命令行输出:
$ echo Some text from stdin | node test.js; echo $?
Stdin has no more data.
Request has finished writing/sending
Works
Response (IncomingMessage) has no more data; exiting with code: 0
0
在 "the server":
$ nc -l 32001 <<EOF
HTTP/1.1 200 OK
Content-Type: text/plain
Works
EOF
POST / HTTP/1.1
Content-Type: text/plain
Host: localhost:32001
Connection: close
Transfer-Encoding: chunked
15
Some text from stdin
0
我正在学习 Node.js 并认为我有一个非常简单的脚本,但任何调整都不会使我的脚本永远挂起。
假设我有一个哑服务器 运行ning:
$ nc -l 32001 <<EOF
HTTP/1.1 200 OK
Content-Type: text/plain
Works
EOF
我运行以下脚本:
var http = require('http');
var options = {
hostname: 'localhost',
port: 32001,
method: 'POST',
headers: {'Content-Type': 'text/plain'}
};
var req = http.request(options, res => {
var exitCode = res.statusCode >= 200 && res.statusCode < 300 ? 0 : 1;
res.pipe(process.stdout).on('end', () => process.exit(exitCode));
});
req.on('error', error => console.error(error));
process.stdin.pipe(req)
.on('end', () => console.log('this does trigger'));
但是当我执行以下操作时:
$ echo foobar | node my-script.js
它只是挂起,永远不会到达请求回调。我希望请求流结束并调用 http.request 回调,然后输出 Works
并最终退出进程。
我检查过 end
事件确实是从 process.stdin.pipe()
调用的,并且我试图在 end
回调中手动结束 req
流。但它不会结束。如何将标准输入通过管道传输到 http.request 并仍然让它结束流?
你走在正确的轨道上;您只需要将您的侦听器附加到适当的对象事件。在第一种情况下(书面的,而不是执行的):
res.pipe(process.stdout).on('end', () => process.exit(exitCode));
你说的:"Pipe the data from response to stdout, and when stdout ends, exit the process."
你的意思:"Pipe the data from response to stdout. When response ends, exit the process." 编码:
res.pipe(process.stdout);
res.on('end', () => process.exit(exitCode));
这里需要明确的一点是,除非您明确关闭 process.stdout
,否则它将 永远不会 close/end 直到您退出该程序。然而,response
将在 HTTP 交互完成时结束。
第二种情况类似:
process.stdin.pipe(req)
.on('end', () => console.log('this does trigger'));
你说的:"Pipe the data from stdin to request, and when request ends, write a message."
你的意思:"Pipe the data from stdin to request. When stdin ends, write a message." 编码:
process.stdin.pipe(req);
process.stdin.on('end', () => console.log('this does trigger'));
这里稍微有些细微差别,因为您可以监听 stdin 的 end
事件或 request 的事件finish
事件:
process.stdin.pipe(req).on('finish', () => console.log('Request has finished writing/sending');
process.stdin.on('end', () => console.log('Stdin has no more data'));
那么,为了完整起见,您的工作客户会回复您,为了假设的教学清晰度,对文本进行了一些轻微的修改:
var http = require('http');
var options = {
hostname: 'localhost',
port: 32001,
method: 'POST',
headers: {'Content-Type': 'text/plain'}
};
var req = http.request(options, res => {
var exitCode = res.statusCode >= 200 && res.statusCode < 300 ? 0 : 1;
res.pipe(process.stdout);
res.on('end', () => {
console.log('Response (IncomingMessage) has no more data; exiting with code:', exitCode);
process.exit(exitCode);
});
});
req.on('error', error => console.error(error));
process.stdin.on('end', () => console.log('Stdin has no more data.'));
process.stdin.pipe(req).on('finish', () => console.log('Request has finished writing/sending'));
命令行输出:
$ echo Some text from stdin | node test.js; echo $?
Stdin has no more data.
Request has finished writing/sending
Works
Response (IncomingMessage) has no more data; exiting with code: 0
0
在 "the server":
$ nc -l 32001 <<EOF
HTTP/1.1 200 OK
Content-Type: text/plain
Works
EOF
POST / HTTP/1.1
Content-Type: text/plain
Host: localhost:32001
Connection: close
Transfer-Encoding: chunked
15
Some text from stdin
0