2017-10-14 115 views
0

我有一点空闲时间,所以我决定用子进程重写JavaScript中的所有bash脚本(NodeJS - ES6)。一切都很顺利,直到我想让用户输入自动化。有什么方法可以确定一个nodejs childprocess是想要输入还是只是发送反馈?

是的,你可以自动执行用户输入。但有一个问题 - 您无法确定给定的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(); 
}); 

上面的例子中工作完全正常。但有两两件事给我一个头痛:

  1. 会直到需要ufw.stdin.write('y\n');等待,如果我有多个输入时会发生什么?例如'是','是','否'。我需要写3行stdin.write()吗?

  2. 是不是我使用ufw.stdin.write('y\n');有点混淆的位置?在我的提示提出输入请求后,我想我需要输入信息,所以我决定更改我的代码,以便我的stdin.write()能够在正确的时间运行,理解正确吗?但是,只有在stdout.on('data', callback)事件中检查“正确”时间的唯一方法。这使得认为有点困难,因为我需要知道,如果提示aksing供用户输入或不...

这里是我的代码,我认为这是完全错误的:

// 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

回答

0

所以我想知道如果它是可能的,它似乎不是。我发布节点的问题,它结束了beeing关闭:https://github.com/nodejs/node/issues/16214

I am asking for a way to determine if the current process is waiting for an input. 

没有一个。我认为你对管道I/O 有错误的期望,因为这根本不是它的工作原理。

谈到期望,检查出预期。如果你环顾四周,可能会有一个 node.js端口。

我会关闭它,因为它不能作为一个功能来实现,而 作为一个问题nodejs/help是更合适的地方。

因此,如果任何人有与我一样的问题,你可以简单地写入多行到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 }); 
相关问题