如何在 Dart 中运行交互式流程?

Stu*_*ham 3 dart dart-io

下面的测试尝试运行 less pager 命令并在用户退出后返回。问题是它不等待用户输入,它只是列出整个文件并退出。平台:xubuntu 12.04,Dart 编辑器版本:13049。

import 'dart:io';

void main() {
  shell('less', ['/etc/mime.types'], (exitCode) => exit(exitCode));
}

void shell(String cmd, List<String> opts, void onExit(int exitCode)) {
  var p = Process.start(cmd, opts);
  p.stdout.pipe(stdout);  // Process output to stdout.
  stdin.pipe(p.stdin);    // stdin to process input.
  p.onExit = (exitCode) {
    p.close();
    onExit(exitCode);
  };
}
Run Code Online (Sandbox Code Playgroud)

以下 CoffeeScript 函数(使用 Nodejs I/O)有效:

shell = (cmd, opts, callback) ->
  process.stdin.pause()
  child = spawn cmd, opts, customFds: [0, 1, 2]
  child.on 'exit', (code) ->
    process.stdin.resume()
    callback code
Run Code Online (Sandbox Code Playgroud)

我怎样才能在 Dart 中实现这个功能?

Mat*_*t B 6

约翰有一个关于如何查看用户输入的很好的例子。但没有回答你原来的问题。不幸的是,您的问题与 Dart 的运作方式不符。您拥有的两个示例(Dart 版本和 CoffeeScript/Node.js 版本)执行两种完全不同的操作。

在您的 CoffeeScript 版本中,spawn 命令实际上是创建一个新进程,然后将执行传递给该新进程。基本上,您的程序不与进程交互通信,而是您的用户与生成的进程交互。

在 Dart 中情况有所不同,您的程序正在与生成的进程进行交互。它不会将执行传递给新进程。基本上,您所做的是将新进程的输入/输出通过管道传输到程序本身。由于您的程序没有距终端的“窗口高度”,因此它会立即传递所有信息。你在 dart 中所做的几乎等同于:

less /etc/mime.types | cat
Run Code Online (Sandbox Code Playgroud)

您可以使用Process.start()与进程进行交互通信。但与进程交互通信的是您的程序,而不是用户。因此,您可以编写一个 dart 程序,该程序将启动并自动播放“zork”或“adventure”等游戏,或者通过查看进程输出的提示来登录远程服务器。

然而,目前还没有办法简单地将执行传递给生成的进程。如果您想将流程输出传达给用户,然后获取用户输入并将其发送回流程,则需要一个附加层。即使如此,并非所有程序(例如 less)的行为都与从 shell 环境启动时的行为相同。