dart子进程无权访问终端

问题描述 投票:0回答:1

我有一个飞镖程序,它会产生一个子飞镖程序。

父飞镖进程可以访问终端,我可以通过呼叫检查该终端:

stdin.hasTerminal

但是,当我调用stdin.hasTerminal时,子飞镖过程返回false。

父进程将每个stdin / stdout / stderr连接到子进程,我认为这是孩子访问终端所需要的全部。

这是我用来生成子飞镖过程的方法:

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'来启动子进程是否可能是问题的一部分。

所以我使用dart2native编译了child.dart脚本,然后更改了父脚本以直接调用新的可执行文件'child'。

但是结果是相同的。即使我直接生成exe时,子级也无法访问终端。

[我应该注意,如果我从cli运行子exe或运行dart child.dart,则子脚本可以访问终端。

dart terminal command-line-interface
1个回答
0
投票

所以事实证明这比预期的要容易。

以下脚本启动vi填充fred.text作为要编辑的文件的名称。

然后代码等待vi完成。

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”结束。

在这种情况下,您无法拦截在子代与终端之间移动的io,但我想不出任何有用的方案。

© www.soinside.com 2019 - 2024. All rights reserved.