如何在请求中使用 child_process spawn 的结果(获取 ENOENT)
How to use the result of child_process spawn in a request (getting ENOENT)
在执行包含以下确切代码的 js 文件时,我遇到了错误。而且我不知道如何解决这个问题。
欢迎任何解释或建议,但我更喜欢我尝试这样做的方式的解决方案。 (当然,除非我在做一些非常愚蠢的事情)
为了测试目的,我写了这个假请求函数:
(function imaginaryRequest(req, res)
{
getDiskInfo('/dev/simfs', info =>
{
console.log(info.ratio)
})
}())
应该使用getDiskInfo
函数,该函数使用child_process.spawn获取df -Ph
输出并将其存储到对象中。
/**
* Get information on the disk space of the specified File system
* @param {string} sysFile (ex: /dev/sda)
* @param {function} callback
* @return {object} df -Ph output stored into object
*/
function getDiskInfo(sysFile, callback) {
const spawn = require('child_process').spawn
const df_Ph = spawn("df -Ph | grep " + sysFile);
df_Ph.stdout.on('data', data => {
let info = data
.split(' ')
.filter(el => el != '')
callback({
maxSpace: info[1],
used: info[2],
unused: info[3],
ratio: info[4],
})
})
df_Ph.stderr.on('data', (data) => {
console.log(`stderr: ${data}`);
});
df_Ph.on('close', (code) => {
console.log(`child process exited with code ${code}`);
});
}
这是我在 shell:
中得到的错误
events.js:160
throw er; // Unhandled 'error' event
^
Error: spawn df -Ph | grep /dev/simfs ENOENT
at exports._errnoException (util.js:1022:11)
at Process.ChildProcess._handle.onexit (internal/child_process.js:193:32)
at onErrorNT (internal/child_process.js:359:16)
at _combinedTickCallback (internal/process/next_tick.js:74:11)
at process._tickCallback (internal/process/next_tick.js:98:9)
at Module.runMain (module.js:607:11)
at run (bootstrap_node.js:420:7)
at startup (bootstrap_node.js:139:9)
at bootstrap_node.js:535:3
谢谢。
首先,派生进程的参数必须以数组的形式作为第二个参数传递给 spawn。您正在获取 ENOENT,因为 spawn 正在寻找名为 df -Ph | grep /dev/simfs
而不是 df
的命令。您也不能在 spawn 中使用管道(因为管道不是进程的参数)。这是 shell 的一个特性,所以一种方法是生成一个 shell,而不是生成一个 shell:
const df_Ph = spawn("sh", ["-c", "df -Ph | grep " + sysFile]);
另一种方法是分别生成 df -Ph
和 grep
,并将第一个进程的标准输出通过管道传输到 grep 进程的标准输入。我相信这是更好的选择,虽然它的代码稍微多一些,但它避免了产生不必要的 sh
进程并且在 IMO 上更具可读性。它看起来像这样:
const df = spawn('df', ['-Ph']);
const grep = spawn('grep', [sysFile], { stdio: [df.stdout, 'pipe', 'pipe'] } );
grep.stdout.on( 'data', data => {
...
在执行包含以下确切代码的 js 文件时,我遇到了错误。而且我不知道如何解决这个问题。
欢迎任何解释或建议,但我更喜欢我尝试这样做的方式的解决方案。 (当然,除非我在做一些非常愚蠢的事情)
为了测试目的,我写了这个假请求函数:
(function imaginaryRequest(req, res)
{
getDiskInfo('/dev/simfs', info =>
{
console.log(info.ratio)
})
}())
应该使用getDiskInfo
函数,该函数使用child_process.spawn获取df -Ph
输出并将其存储到对象中。
/**
* Get information on the disk space of the specified File system
* @param {string} sysFile (ex: /dev/sda)
* @param {function} callback
* @return {object} df -Ph output stored into object
*/
function getDiskInfo(sysFile, callback) {
const spawn = require('child_process').spawn
const df_Ph = spawn("df -Ph | grep " + sysFile);
df_Ph.stdout.on('data', data => {
let info = data
.split(' ')
.filter(el => el != '')
callback({
maxSpace: info[1],
used: info[2],
unused: info[3],
ratio: info[4],
})
})
df_Ph.stderr.on('data', (data) => {
console.log(`stderr: ${data}`);
});
df_Ph.on('close', (code) => {
console.log(`child process exited with code ${code}`);
});
}
这是我在 shell:
中得到的错误events.js:160
throw er; // Unhandled 'error' event
^
Error: spawn df -Ph | grep /dev/simfs ENOENT
at exports._errnoException (util.js:1022:11)
at Process.ChildProcess._handle.onexit (internal/child_process.js:193:32)
at onErrorNT (internal/child_process.js:359:16)
at _combinedTickCallback (internal/process/next_tick.js:74:11)
at process._tickCallback (internal/process/next_tick.js:98:9)
at Module.runMain (module.js:607:11)
at run (bootstrap_node.js:420:7)
at startup (bootstrap_node.js:139:9)
at bootstrap_node.js:535:3
谢谢。
首先,派生进程的参数必须以数组的形式作为第二个参数传递给 spawn。您正在获取 ENOENT,因为 spawn 正在寻找名为 df -Ph | grep /dev/simfs
而不是 df
的命令。您也不能在 spawn 中使用管道(因为管道不是进程的参数)。这是 shell 的一个特性,所以一种方法是生成一个 shell,而不是生成一个 shell:
const df_Ph = spawn("sh", ["-c", "df -Ph | grep " + sysFile]);
另一种方法是分别生成 df -Ph
和 grep
,并将第一个进程的标准输出通过管道传输到 grep 进程的标准输入。我相信这是更好的选择,虽然它的代码稍微多一些,但它避免了产生不必要的 sh
进程并且在 IMO 上更具可读性。它看起来像这样:
const df = spawn('df', ['-Ph']);
const grep = spawn('grep', [sysFile], { stdio: [df.stdout, 'pipe', 'pipe'] } );
grep.stdout.on( 'data', data => {
...