Запуск сценария оболочки из Nodejs

У меня есть сценарий оболочкиstart.sh, чья работа состоит в том, чтобы породить несколько процессов java в фоновом режиме, а затем выйти нормально, как так:

java -jar jar1.jar &
java -jar jar2.jar &
...
exit 0

Куча выхода напечатана:

Starting jar1
Starting jar2
...

Теперь я хочу, чтобы nodejs вызывал start.shотслеживание вывода, чтобы я мог действовать на нем, когда starter.shэто будет сделано

Проблема Nodejs считаетstarter.sh, что будет сделано только тогда, когда все процессы java, которые были запущены мертвы.
Что странно, потому что из оболочки, starter.shвыходит сразу и больше не имеет никаких отношений с процессами java

Как я могу заставить starter.shвести себя таким же образом при вызове из узла?

Это код, который я использую для создания starter.sh:

  const process = spawn('starter.sh', []);

  process.stdout.on('data', (data) => {
    console.log(`stdout: ${data}`);
    // prints 'Starting jarx' like expected
  });

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

  process.on('close', (code) => {
    console.log(`child process exited with code ${code}`);
    // Not called unless all the spawned java processes are dead :(
  });

1 ответ

  1. У меня есть чувство, что моя проблема связана с дочерними процессами, общими stdioс родительским узлом. Действительно, где бы javaпроцессы писали, если бы им не нужно было stdoutписать. Таким образом, узел должен ждать, пока они будут сделаны, чтобы считать starter.shсделано

    Я решил дать дочернему процессу его собственный stdioи записать starter.shвыходные данные в файл:

      const out = fs.openSync('/tmp/command.out', 'w');
      const err = fs.openSync('/tmp/command.err', 'w');
    
      const process = spawn(command, args, {detached: true, stdio: ['ignore', out , err]});
      process.unref();
    
      process.on('close', (code) => {
        console.log(`child process exited with code ${code}`);
        console.log(fs.readFileSync('/tmp/command.out', 'utf8');
        console.log(fs.readFileSync('/tmp/command.err', 'utf8'));
      });
    

    Таким образомclose, обратный вызов вызывается, как только starter.shэто сделано, и я все еще могу получить доступ к его выходу.