Как использовать результат появления потомка child_process в запросе (получение ENOENT)

Я получаю 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}`);
  });
}

И вот ошибка, которую я получаю в оболочке:

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

Спасибо.

1 ответ

Решение

Во-первых, аргументы вашего порожденного процесса должны передаваться в массиве как второй аргумент для порождения. Вы получаете ENOENT, потому что spawn ищет команду под названием df -Ph | grep /dev/simfsне df, Вы также не можете использовать трубу в spawn (так как труба не является аргументом процесса). Это особенность оболочки, поэтому одним из способов сделать то, что вы хотите, было бы вместо этого создать оболочку:

const df_Ph = spawn("sh", ["-c", "df -Ph | grep " + sysFile]);

Другой должен порождать df -Ph а также grep отдельно и передайте стандартный поток первых процессов на стандартный процесс grep. Я считаю, что это лучший вариант, хотя он немного больше кода, он позволяет избежать ненужного sh процесс и более читаемый ИМО. Это будет выглядеть примерно так:

const df = spawn('df', ['-Ph']);                                                                                                                                                                                   
const grep = spawn('grep', [sysFile], { stdio: [df.stdout, 'pipe', 'pipe'] } );

grep.stdout.on( 'data', data => {
    ...
Другие вопросы по тегам