2017-10-14 117 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 }); 
相關問題