дочерний процесс dart не имеет доступа к терминалу - PullRequest
0 голосов
/ 02 февраля 2020

У меня есть процесс дартс, который порождает дочерний процесс дартс.

Родительский процесс дартс имеет доступ к терминалу, который я могу проверить с помощью вызова:

stdin.hasTerminal

Дочерний дартс Однако процесс возвращает false, когда я вызываю stdin.hasTerminal.

Родительский процесс связывает каждый из stdin / stdout / stderr с дочерним процессом, и это все, что, как я думал, потребуется для того, чтобы у ребенка был доступ к терминалу.

Вот метод, который я использую для порождения дочернего процесса dart:

parent.dart

import 'dart:async';
import 'dart:cli';
import 'dart:io';

void main() {
  print('parent hasTerminal=${stdin.hasTerminal}');
  // Execute the script
  final process = waitFor<Process>(Process.start('dart', ['child.dart']));

  // Pipe std out and in
  final StreamSubscription stderrSub =
      process.stderr.listen((List<int> d) => stderr.add(d));
  final StreamSubscription stdoutSub =
      process.stdout.listen((List<int> d) => stdout.add(d));
  final StreamSubscription stdinSub =
      stdin.listen((List<int> d) => process.stdin.add(d));

  final exitCode = waitFor<int>(process.exitCode);

  final futures = <Future<void>>[];

  futures.add(stderrSub.cancel());
  futures.add(stdoutSub.cancel());
  futures.add(stdinSub.cancel());

  waitFor<void>(Future.wait(futures));

  exit(exitCode);
}

И это дочерний процесс, который я порождаю:

child.dart

import 'dart:io';

void main() {
  print('child: has terminal: ${stdin.hasTerminal}');
}

Вы можете запустить пример, поместив оба файла в один каталог и запустив:

dart parent.dart

Когда я запускаю Приложение, которое я получаю:

dart parent.dart 
parent hasTerminal=true
child: has terminal: false

Мне было интересно, если использование dart child.dart для запуска дочернего процесса может быть частью проблемы.

Поэтому я скомпилировал скрипт child.dart используя dart2native, а затем изменил родительский скрипт на прямой вызов l новый исполняемый файл 'child'.

Однако результаты были такими же. Даже когда я создал exe-файл напрямую, дочерний элемент не имеет доступа к терминалу.

Следует отметить, что если я запускаю дочерний exe-файл или запускаю dart child.dart из cli, дочерний сценарий имеет доступ к терминалу.

1 Ответ

0 голосов
/ 03 февраля 2020

Так что это оказалось проще, чем ожидалось.

Следующий скрипт запускает vi padding fred.text в качестве имени файла для редактирования.

Затем код ожидает vi до конечного значения sh.

import 'dart:cli';
import 'dart:io';

void main()
{
  // Execute the script
    final process = waitFor<Process>(Process.start('vi', ['fred.text'],
        mode: ProcessStartMode.inheritStdio));

    final exitCode = waitFor<int>(process.exitCode);
}

Метод Process.start имеет режим 'inheritStdio'. Когда вы устанавливаете этот дротик, присоединяет дочерний процесс непосредственно к терминалу.

Первый вызов waitFor заставляет скрипт ждать запуска 'vi', а второй waitFor заставляет скрипт ждать 'vi' конец.

В этом сценарии вы не можете перехватить перемещение между дочерним устройством и терминалом, но я не могу вспомнить ни одного сценария ios, где это было бы полезно.

...