有什么方法可以确定 nodejs 子进程是否需要输入或只是发送反馈?
Is there any way to determine if a nodejs childprocess wants input or is just sending feedback?
我有一点空闲时间,所以我决定用子进程重写 JavaScript (NodeJS - ES6) 中的所有 bash 脚本。一切都很顺利,直到我想自动化用户输入。
是的,您可以自动执行用户输入。但是有一个问题 - 您无法确定给定的 data
事件是反馈还是输入请求。至少我找不到办法。
所以基本上你可以这样做:
// new Spawn.
let spawn = require('child_process');
// new ufw process.
let ufw = spawn('ufw', ['enable']);
// Use defined input.
ufw.stdin.setEncoding('utf-8');
ufw.stdout.pipe(process.stdout);
ufw.stdin.write('y\n');
// Event Standard Out.
ufw.stdout.on('data', (data) => {
console.log(data.toString('utf8'));
});
// Event Standard Error.
ufw.stderr.on('data', (err) => {
// Logerror.
console.log(err);
});
// When job is finished (with or without error) it ends up here.
ufw.on('close', (code) => {
// Check if there were errors.
if (code !== 0) console.log('Exited with code: ' + code.toString());
// End input stream.
ufw.stdin.end();
});
上面的例子完全没问题。但是有两件事让我很头疼:
是否会 ufw.stdin.write('y\n');
等到需要它时,如果我有多个输入会怎样?例如 'yes'、'yes'、'no'。一定要写3行stdin.write()
吗?
我用ufw.stdin.write('y\n');
的位置是不是有点乱?我认为在我的提示发出输入请求后我需要输入,所以我决定更改我的代码,使我的 stdin.write()
可以在正确的时间 运行,对吧?但是,检查 'right' 时间的唯一方法是在 stdout.on('data', callback)
事件上。这让思考有点困难,因为我需要知道提示是否要求用户输入...
这是我认为完全错误的代码:
// new Spawn.
let spawn = require('child_process');
// new ufw process.
let ufw = spawn('ufw', ['enable']);
// Event Standard Out.
ufw.stdout.on('data', (data) => {
console.log(data.toString('utf8'));
// Use defined input.
ufw.stdin.setEncoding('utf-8');
ufw.stdout.pipe(process.stdout);
ufw.stdin.write('y\n');
});
// Event Standard Error.
ufw.stderr.on('data', (err) => {
// Logerror.
console.log(err);
});
// When job is finished (with or without error) it ends up here.
ufw.on('close', (code) => {
// Check if there were errors.
if (code !== 0) console.log('Exited with code: ' + code.toString());
// End input stream.
ufw.stdin.end();
});
我的主要误解是何时使用 stdin
进行用户输入(自动)以及将其放置在我的代码中的什么位置以便在正确的时间使用它,例如,如果我有多个输入的东西像 mysql_secure_installation
.
所以我想知道是否可能,但似乎不可能。我发布了一个节点问题,最终被关闭:https://github.com/nodejs/node/issues/16214
I am asking for a way to determine if the current process is waiting for an input.
There isn't one. I think you have wrong expectations about pipe I/O
because that's simply not how it works.
Talking about expectations, check out expect. There is probably a
node.js port if you look around.
I'll close this out because it's not implementable as a feature, and
as a question nodejs/help is the more appropriate place.
因此,如果有人遇到与我相同的问题,您只需将多行写入 stdin
并将其用作预定义值即可。请记住,如果功能更新中的任何输入损坏或错误,最终将中断流:
// new Spawn.
let spawn = require('child_process');
// new msqlsec process.
let msqlsec = spawn('mysql_secure_installation', ['']);
// Arguments as Array.
let inputArgs = ['password', 'n', 'y', 'y', 'y', 'y'];
// Set correct encodings for logging.
msqlsec.stdin.setEncoding('utf-8');
msqlsec.stdout.setEncoding('utf-8');
msqlsec.stderr.setEncoding('utf-8');
// Use defined input and write line for each of them.
for (let a = 0; a < inputArgs.length; a++) {
msqlsec.stdin.write(inputArgs[a] + '\n');
}
// Event Standard Out.
msqlsec.stdout.on('data', (data) => {
console.log(data.toString('utf8'));
});
// Event Standard Error.
msqlsec.stderr.on('data', (err) => {
// Logerror.
console.log(err);
});
// When job is finished (with or without error) it ends up here.
msqlsec.on('close', (code) => {
// Check if there were errors.
if (code !== 0) console.log('Exited with code: ' + code.toString());
// close input to writeable stream.
msqlsec.stdin.end();
});
为了完整起见,如果有人想手动填写用户输入,您可以像这样简单地启动给定过程:
// new msqlsec process.
let msqlsec = spawn('mysql_secure_installation', [''], { stdio: 'inherit', shell: true });
我有一点空闲时间,所以我决定用子进程重写 JavaScript (NodeJS - ES6) 中的所有 bash 脚本。一切都很顺利,直到我想自动化用户输入。
是的,您可以自动执行用户输入。但是有一个问题 - 您无法确定给定的 data
事件是反馈还是输入请求。至少我找不到办法。
所以基本上你可以这样做:
// new Spawn.
let spawn = require('child_process');
// new ufw process.
let ufw = spawn('ufw', ['enable']);
// Use defined input.
ufw.stdin.setEncoding('utf-8');
ufw.stdout.pipe(process.stdout);
ufw.stdin.write('y\n');
// Event Standard Out.
ufw.stdout.on('data', (data) => {
console.log(data.toString('utf8'));
});
// Event Standard Error.
ufw.stderr.on('data', (err) => {
// Logerror.
console.log(err);
});
// When job is finished (with or without error) it ends up here.
ufw.on('close', (code) => {
// Check if there were errors.
if (code !== 0) console.log('Exited with code: ' + code.toString());
// End input stream.
ufw.stdin.end();
});
上面的例子完全没问题。但是有两件事让我很头疼:
是否会
ufw.stdin.write('y\n');
等到需要它时,如果我有多个输入会怎样?例如 'yes'、'yes'、'no'。一定要写3行stdin.write()
吗?我用
ufw.stdin.write('y\n');
的位置是不是有点乱?我认为在我的提示发出输入请求后我需要输入,所以我决定更改我的代码,使我的stdin.write()
可以在正确的时间 运行,对吧?但是,检查 'right' 时间的唯一方法是在stdout.on('data', callback)
事件上。这让思考有点困难,因为我需要知道提示是否要求用户输入...
这是我认为完全错误的代码:
// new Spawn.
let spawn = require('child_process');
// new ufw process.
let ufw = spawn('ufw', ['enable']);
// Event Standard Out.
ufw.stdout.on('data', (data) => {
console.log(data.toString('utf8'));
// Use defined input.
ufw.stdin.setEncoding('utf-8');
ufw.stdout.pipe(process.stdout);
ufw.stdin.write('y\n');
});
// Event Standard Error.
ufw.stderr.on('data', (err) => {
// Logerror.
console.log(err);
});
// When job is finished (with or without error) it ends up here.
ufw.on('close', (code) => {
// Check if there were errors.
if (code !== 0) console.log('Exited with code: ' + code.toString());
// End input stream.
ufw.stdin.end();
});
我的主要误解是何时使用 stdin
进行用户输入(自动)以及将其放置在我的代码中的什么位置以便在正确的时间使用它,例如,如果我有多个输入的东西像 mysql_secure_installation
.
所以我想知道是否可能,但似乎不可能。我发布了一个节点问题,最终被关闭:https://github.com/nodejs/node/issues/16214
I am asking for a way to determine if the current process is waiting for an input.
There isn't one. I think you have wrong expectations about pipe I/O because that's simply not how it works.
Talking about expectations, check out expect. There is probably a node.js port if you look around.
I'll close this out because it's not implementable as a feature, and as a question nodejs/help is the more appropriate place.
因此,如果有人遇到与我相同的问题,您只需将多行写入 stdin
并将其用作预定义值即可。请记住,如果功能更新中的任何输入损坏或错误,最终将中断流:
// new Spawn.
let spawn = require('child_process');
// new msqlsec process.
let msqlsec = spawn('mysql_secure_installation', ['']);
// Arguments as Array.
let inputArgs = ['password', 'n', 'y', 'y', 'y', 'y'];
// Set correct encodings for logging.
msqlsec.stdin.setEncoding('utf-8');
msqlsec.stdout.setEncoding('utf-8');
msqlsec.stderr.setEncoding('utf-8');
// Use defined input and write line for each of them.
for (let a = 0; a < inputArgs.length; a++) {
msqlsec.stdin.write(inputArgs[a] + '\n');
}
// Event Standard Out.
msqlsec.stdout.on('data', (data) => {
console.log(data.toString('utf8'));
});
// Event Standard Error.
msqlsec.stderr.on('data', (err) => {
// Logerror.
console.log(err);
});
// When job is finished (with or without error) it ends up here.
msqlsec.on('close', (code) => {
// Check if there were errors.
if (code !== 0) console.log('Exited with code: ' + code.toString());
// close input to writeable stream.
msqlsec.stdin.end();
});
为了完整起见,如果有人想手动填写用户输入,您可以像这样简单地启动给定过程:
// new msqlsec process.
let msqlsec = spawn('mysql_secure_installation', [''], { stdio: 'inherit', shell: true });