我有一个飞镖程序,它会产生一个子飞镖程序。
父飞镖进程可以访问终端,我可以通过呼叫检查该终端:
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
,则子脚本可以访问终端。
所以事实证明这比预期的要容易。
以下脚本启动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,但我想不出任何有用的方案。