Как отправить CTRL+C дочернему процессу в Node.js?

Я попытался создать дочерний процесс - vvp (https://linux.die.net/man/1/vvp). В определенное время мне нужно отправить этому процессу CTRL+C. Я ожидаю, что симуляция будет прервана, и получаю интерактивную подсказку. И после этого я могу продолжить симуляцию, отправив команду дочернему процессу. Итак, я попробовал что-то вроде этого:

var child = require('child_process');
var fs = require('fs');
var vcdGen = child.spawn('vvp', ['qqq'], {});

vcdGen.stdout.on('data', function(data) {
  console.log(data.toString())
});

setTimeout(function() {
  vcdGen.kill('SIGINT');
}, 400);

В этом случае дочерний процесс был остановлен. Я также пробовал vcdGen.stdin.write('\x03') вместо vcdGen.kill('SIGINT');, но это не работает.

Может это из-за винды? Есть ли способ добиться того же поведения, что и в cmd?


person Alexandr    schedule 01.02.2017    source источник
comment
Добавлен тег Windows (критически важный для вопроса) и, следовательно, cmd не нужен (и порождение более конкретно, чем дочерний процесс)   -  person Richard    schedule 01.02.2017
comment
@Richard Не говоря уже о том, что cmd вообще не участвует - это просто командный процессор, который не имеет ничего общего с консольной подсистемой (кроме того, что это консольное приложение, как и любое другое, конечно).   -  person Luaan    schedule 01.02.2017


Ответы (1)


kill действительно поддерживает только грубое уничтожение процесса в Windows - модель сигнала приложения в Windows и * nix несовместима. Вы не можете передать Ctrl+C через стандартный ввод, потому что он никогда не проходит через стандартный ввод — это функция консольной подсистемы (и, следовательно, вы можете использовать ее только в том случае, если к процессу подключена консоль). Он создает новый поток в дочернем процессе для выполнения своей работы.

Нет поддерживаемого способа сделать это программно. Это функция для пользователя, а не для приложений. Единственный способ сделать это — сделать то же самое, что делает консольная подсистема — создать новый поток в целевом приложении и позволить ему выполнять сигнализацию. Но лучше всего было бы вместо этого просто использовать совместную передачу сигналов, хотя это, конечно, требует, чтобы вы изменили целевое приложение, чтобы понять сигнал.

Если вы хотите пойти совершенно неподдерживаемым маршрутом, посмотрите https://stackoverflow.com/a/1179124/3032289.

Если вы хотите найти золотую середину, конечно, есть способ послать сигнал себе. Это также означает, что вы можете отправить Ctrl+C процессу, если ваши консоли подключены. Излишне говорить, что это очень сложно - вы, вероятно, захотите создать собственный хост-процесс, который ничего не делает, кроме создания консоли и запуска реальной программы, которую вы хотите запустить. Затем ваш хост-процесс прослушивает событие и, когда о событии поступает сигнал, вызывает GenerateConsoleCtrlEvent.

person Luaan    schedule 01.02.2017