Я написал сценарий узла для управления развертыванием репозитория git в группе автоматического масштабирования AWS.
Скрипт использует child_process.spawn () для автоматизации git, клонирования репозиториев, тегов извлечения и т. Д.
Работает нормально, если git может найти подходящие учетные данные.Однако, если учетные данные не найдены автоматически, то порожденный процесс попытается запросить учетные данные и в этот момент зависнет.Даже Ctrl-C не может выйти.Весь сеанс оболочки должен быть закончен.
Вызов spawn () обернут в функцию для возврата Promise.Моя функция выглядит так ...
const cp = require('child_process');
let spawn_promise = (command, args, options, stream_output) => {
return new Promise((resolve, reject) => {
console.log(chalk.cyan(`${command} [${args}]`));
let childProcess = cp.spawn(command, args, options);
let std_out = '';
let std_err = '';
childProcess.stdout.on('data', function (data) {
std_out += data.toString();
if (stream_output)
console.log(chalk.green(data.toString()));
});
childProcess.stderr.on('data', function (data) {
std_err += data.toString();
if (stream_output)
console.log(chalk.red(data.toString()));
});
childProcess.on('close', (code) => {
if (code === 0) {
console.log(chalk.blue(`exit_code = ${code}`));
return resolve(std_out);
}
else {
console.log(chalk.yellow(`exit_code = ${code}`));
return reject(std_err);
}
});
childProcess.on('error', (error) => {
std_err += error.toString();
if (stream_output)
console.log(chalk.red(error.toString()));
});
});
}
Я называю это так ...
return spawn_promise('git', ['fetch', '--all'], {env: process.env})
.then(() => {
...
В основном это работает очень хорошо, и позволяет легко манипулировать выходными данными, ошибками и т. Д.
У меня проблемы с поиском хорошего способа обработки ввода, хотя, если это требуется для порожденного процесса.
Временное решение проблемы - добавить переменную среды взапретить git запрашивать учетные данные и вместо этого выдать ошибку, если он не может найти учетные данные в среде пользователя.Однако это не идеально.В идеале я хотел бы иметь возможность корректно обрабатывать стандартный ввод и при этом сохранять и обрабатывать вывод и ошибки, как я делаю в настоящее время.
Я могу решить проблему с вводом, выполнив это ...
let childProcess = cp.spawn(command, args, { stdio: [process.stdin, process.stdout, process.stderr] });
Это позволяет git правильно запрашивать учетные данные.Однако затем я теряю способность перехватывать выходные данные команды.
Как правильно справиться с этим?
Я должен также упомянуть, что эта функция также автоматизирует некоторые относительно длительные работы.процессы, для создания AMI и т. д. Это то, для чего предназначен параметр «stream_output».Я хочу иметь возможность просматривать вывод команды в режиме реального времени, а не ждать, пока процесс завершится.