Nodejs: запись в stdin сбоев процесса bash с помощью EPIPE - PullRequest
0 голосов
/ 26 октября 2018

Мой процесс узла получает некоторый PDF-файл через HTTP-запрос, затем использует событие onData запроса для передачи входящих данных в правильно настроенный lpr, порожденный через child_process.exec. Я пишу в стандартный ввод, используя process.stdin.write(...), а затем process.stdin.end(), когда закончите. Это позволяет мне немедленно распечатать эти файлы.

Теперь у меня есть ситуация, когда я не хочу, чтобы данные передавались по lpr, а к какому-то bash-скрипту. Сценарий использует cat для обработки stdin.

myscript.sh < somefile.pdf работает как положено, как и cat somefile.pdf | myscript.sh.

Однако, когда я порождаю /path/to/script.sh из узла (просто заменяя lpr на путь сценария в источнике), процесс завершается с

events.js:183 throw er; // Unhandled 'error' event ^ Error: write EPIPE at WriteWrap.afterWrite [as oncomplete] (net.js:868:14)

Впоследствии происходит сбой всего процесса узла, и ошибка распространяется вокруг всех try...catch блоков. Запись в начале скрипта bash показывает, что он даже не запускается.

Когда я нацеливаюсь на что-либо, кроме сценария оболочки, а на какой-то скомпилированный исполняемый файл, например cat, echo, ... все работает просто отлично. Добавление модуля epipebomb ничего не изменит.

Я также попытался передать по трубопроводу на process.exec("bash", ["-c cat | myscript.sh"]) с теми же ошибками.

Пример сценария bash, просто для проверки на выполнение:

#!/usr/bin/env bash
date > logfile.txt
cat > /dev/null

EDIT: Я думаю, что мне, возможно, нужно дать сигнал, чтобы поток STDIN был как-то открыт. Часть сценария, порождающая процесс, исключающая обработку обещаний и вывода:

const process = require("child_process")    

// inputObservable being an rxjs Observable
execstuff(inputObervable) {
  const task = process.spawn("/path/to/script.sh");
  inputObservable.subscribe(
    chunk => task.stdin.write(chunk),
    error => console.error(error),
    finished => task.stdin.end()
  );
}

1 Ответ

0 голосов
/ 26 октября 2018

В child_process.spawn есть пример того, как вы можете написать следующие строки ps ax | grep ssh в виде сценария node.js, возможно, это будет полезно для вас:

const { spawn } = require('child_process');
const ps = spawn('ps', ['ax']);
const grep = spawn('grep', ['ssh']);

ps.stdout.on('data', (data) => {
  grep.stdin.write(data);
});

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

Первое впечатление, что вы делаете то же самое, проблема может быть в данных чанка, возможно, один из чанков нулевой, и он закрывает поток, и вы хотите закрыть его, запустив task.stdin .end ().

Другая вещь, которую вы можете попробовать, - запустить скрипт node.js с NODE_DEBUG=stream node script.js Записывает внутреннее содержимое узла node.js, как ведет себя поток, также может быть полезным для вас.

...