你如何在Dart中运行一个交互式过程?

时间:2012-10-01 22:56:16

标签: 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);
  };
}

以下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

如何在Dart中完成这项工作?

2 个答案:

答案 0 :(得分:4)

John有一个关于如何查看用户输入的好例子。但是没有回答你原来的问题。不幸的是,您的问题与Dart的运作方式不符。你拥有的两个例子,Dart版本和CoffeeScript / Node.js版本,做了两件完全不同的事情。

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

在Dart中它与众不同,您的程序正在与生成的进程交互。它并没有将执行权交给新进程。基本上你正在做的是将新进程的输入/输出连接到程序本身。由于您的程序没有终端的“窗口高度”,它会立即传递所有信息。你在飞镖上做的几乎相当于:

less /etc/mime.types | cat

您可以使用Process.start()与流程进行交互式通信。但是,您的程序与流程进行交互式通信,而不是用户。因此,您可以编写一个飞镖程序,例如启动并自动播放“zork”或“冒险”,或者通过查看进程输出的提示登录到远程服务器。

但是,目前没有办法简单地将执行传递给生成的进程。如果要将流程输出传达给用户,然后还要获取用户输入并将其发送回流程,则需要额外的层。即便如此,并非所有程序(例如较少)的行为与从shell环境启动时的行为相同。

答案 1 :(得分:3)

这是从用户读取控制台输入的基本结构。此示例从用户读取文本行,并退出'q':

import 'dart:io';
import 'dart:isolate';

final StringInputStream textStream = new StringInputStream(stdin);

void main() {
  textStream.onLine = checkBuffer;
}


void checkBuffer(){
    final line = textStream.readLine();

    if (line == null) return;

    if (line.trim().toLowerCase() == 'q'){
        exit(0);
    }

    print('You wrote "$line".  Now write something else!');
}