Node.js Spawn Display STDOUT live не работает

У меня есть приложение, оно получает ссылки на файлы и скачивает их, для скачивания я использую aria2c.

Для этого сначала я использовал exec, но, поскольку я хочу получить ход загрузки, я использовал spawn

Вот код, который я использую для загрузки файла с помощью aria2c:

'use strict';

const
    spawn = require( 'child_process' ).spawn,
    aria2c = spawn( 'aria2c', ['-x8', 'https://wa-us-ping.vultr.com/vultr.com.100MB.bin' ] );

aria2c.stdout.on( 'data', data => {
    console.log( `stdout: ${data}` );
});

aria2c.stderr.on( 'data', data => {
    console.log( `stderr: ${data}` );
});

aria2c.on( 'close', code => {
    console.log( `child process exited with code ${code}` );
});

Когда я запускаю этот код, он не выводит вывод aria2c на стандартный вывод, он показывает его только после завершения загрузки.

Я хочу знать, как я могу это исправить.


person user1086010    schedule 24.05.2017    source источник


Ответы (1)


Я не очень хорошо знаю aria2c, но вот что я придумал:

// enable a specific log level
aria2c = spawn( 'aria2c', ['--log-level=info', '-l-', '-x8', 'https://wa-us-ping.vultr.com/vultr.com.100MB.bin' ]);

// find the percentage (this is not well-tested...)
aria2c.stdout.on( 'data', data => {
  data = data.toString();
  if (/ETA:/.test(data)) {
    let pct = data.match(/\(.*?%\)/)[0];
    console.log( `stdout: ${ pct }` );
  }
});

(остальная часть кода остается прежней)

Причина, по которой вы не можете (легко) захватить вывод по умолчанию, заключается в том, что строки выполнения заканчиваются только возвратом каретки, а не новой строкой, что приводит к буферизации этих строк, и вы получите одно событие data в конце который содержит все эти строки.

Изменяя уровень журнала, строки выполнения перемежаются с другими строками, что либо ускоряет заполнение буфера, либо приводит к большему количеству сбросов ввода-вывода, поэтому событие data срабатывает чаще, позволяя вам захватывать данные о ходе выполнения.

person robertklep    schedule 24.05.2017