dart子进程无权访问终端 [英] dart child process doesn't have access to terminal

查看:69
本文介绍了dart子进程无权访问终端的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a dart process which spawns a child dart process.

父级dart进程可以访问终端,我可以通过呼叫进行检查:

The parent dart process has access to the terminal which I can check via the call:

stdin.hasTerminal

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

The child dart process however returns false when I call stdin.hasTerminal.

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

The parent process wires each of stdin/stdout/stderr to the child process which is all I thought would be required for the child to have access to the terminal.

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

Here is the method I use to spawn the child dart process:

parent.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

child.dart

import 'dart:io';

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

您可以通过将两个文件放在同一目录中并运行来运行该示例:

You can run the example by placing both files in the same directory and running:

dart parent.dart

dart parent.dart

当我运行该应用程序时,我得到:

When I run the app I get:

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

我确实想知道使用'dart child.dart'启动子进程是否可能是问题的一部分.

I did wonder if using 'dart child.dart' to start the child process might be part of the problem.

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

So I compiled the child.dart script using dart2native and then changed the parent script to directly call the new executable 'child'.

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

The results were however the same. Even when I spawned the exe directly child does not have access to the terminal.

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

I should note that if I run the child exe or run dart child.dart from the cli then the child script has access to the terminal.

推荐答案

因此,这比预期的要容易.

So this turned out to be easier than expected.

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

The following script launches vi padding fred.text as the name of the file to edit.

然后,代码等待 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".设置此镖后,子进程将直接附加到终端.

The Process.start method has a mode 'inheritStdio'. When you set this dart attaches the child process directly to the terminal.

第一次调用waitFor导致脚本等待"vi"开始,第二个waitFor导致脚本等待"vi"结束.

The first call to waitFor causes the script to wait for 'vi' to start and the second waitFor causes the script to wait for 'vi' to end.

在这种情况下,您无法拦截在子代和终端之间移动的io,但我无法想到任何有用的情况.

In this scenario you can't intercept the io moving between the child and the terminal but I can't think of any scenarios where this would be useful.

这篇关于dart子进程无权访问终端的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆