Как отправить stdout / stderr процессу дедушки и бабушки? - PullRequest
0 голосов
/ 22 декабря 2018

У меня есть этот код node.js:

 const k = cp.spawn('bash');

    k.stdin.end(`

        set -e;
        echo; echo; echo 'du results:';
        ( cd "${extractDir}" && tar -xzvf "${createTarball.pack.value}" ) > /dev/null;
        find "${extractDir}/package" -type f | xargs du --threshold=500KB;

    `);

    k.stdout.pipe(pt(chalk.redBright('this is a big file (>500KB) according to du: '))).pipe(process.stdout);
    k.stderr.pipe(pt(chalk.magenta('du stderr: '))).pipe(process.stderr);

проблема в том, что несколько внуков будут записывать все свои stdout / stderr в родительский.

Я хочу сделать что-то вроде этоговместо этого:

 const pid = process.pid;

 const k = cp.spawn('bash');

    k.stdin.end(`


        set -e;

        exec 3<>/proc/${pid}/fd/1

        echo > 3 ; echo > 3; echo 'du results:' > 3;

        ( cd "${extractDir}" && tar -xzvf "${createTarball.pack.value}" ) > /dev/null;
        find "${extractDir}/package" -type f | xargs du --threshold=500KB ;

    `);

    k.stdout.pipe(pt(chalk.redBright('this is a big file (>500KB) according to du: '))).pipe(process.stdout);
    k.stderr.pipe(pt(chalk.magenta('du stderr: '))).pipe(process.stderr);

, но этот метод не будет работать на MacOS, потому что Mac не имеет функции / proc / pid fs.Кто-нибудь знает, что я пытаюсь сделать и, возможно, хороший обходной путь?

Ответы [ 2 ]

0 голосов
/ 22 декабря 2018

Так что я решил эту проблему по-другому, OP был немного вопросом XY - поэтому я в основном использую mkfifo, так как я на MacOS и у меня нет файла /proc/<pid>:

сначаламы называем это:

mkfifo "$fifoDir/fifo"

и затем у нас есть

    const fifo = cp.spawn('bash');
    fifo.stdout.setEncoding('utf8');

    fifo.stdout
      .pipe(pt(chalk.yellow.bold('warning: this is a big file (>5KB) according to du: ')))
      .pipe(process.stdout);

    fifo.stdin.end(`

        while true; do
          cat "${fifoDir}/fifo"
        done

    `);

    const k = cp.spawn('bash');

    k.stdin.end(`

        set -e;
        echo; echo 'du results:';
        tar -xzvf "${createTarball.pack.value}" -C "${extractDir}" > /dev/null;
        ${cmd} > "${fifoDir}/fifo";
        kill -INT ${fifo.pid};

    `);

    k.stdout.pipe(process.stdout);
    k.stderr.pipe(pt(chalk.magenta('du stderr: '))).pipe(process.stderr);

    k.once('exit', code => {

      if (code > 0) {
        log.error('Could not run cmd:', cmd);
      }

      cb(code);
    });

  },

дочерний процесс "fifo" - это родственный процесс для процесса k, что очевидно, когда вы смотрите на приведенный выше кодблок, и процесс "fifo" завершает обработку stdout одного из подпроцессов процесса k - они взаимодействуют посредством именованного канала (mkfifo).

0 голосов
/ 22 декабря 2018

Установите libsys или другие способы создания необработанных системных вызовов из узла.Затем выполните системный вызов dup(2) с 1 в качестве аргумента и сохраните результат в переменной fd.Как только вы это сделаете, fd будет номером дескриптора файла, который является дубликатом stdout узла, и он будет наследоваться дочерними процессами.В этот момент просто удалите exec 3<>/proc/${pid}/fd/1 из bash и замените все свои >&3 s на >&${fd} s.

...