【问题标题】:How do you run an interactive process in Dart?你如何在 Dart 中运行一个交互式进程?
【发布时间】:2012-10-01 22:56:16
【问题描述】:

下面的测试尝试运行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 中完成这项工作?

【问题讨论】:

    标签: dart dart-io


    【解决方案1】:

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

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

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

    less /etc/mime.types | cat
    

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

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

    【讨论】:

    • 我计划在上述答案中包含一些示例代码,但是目前似乎存在一个错误,阻止了进程的输出被交互式读取。看起来缓冲区在进程终止流之后才被进程刷新。等待dartbug.com/5607 然后我会发布代码:)
    • 感谢您的精彩解释(以及您在 issue 5607 中发布的代码),我不再需要一直用头撞墙 :-)
    【解决方案2】:

    这是从用户读取控制台输入的基本结构。此示例从用户处读取文本行,并在 '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!');
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-17
      • 1970-01-01
      • 2018-09-04
      • 1970-01-01
      相关资源
      最近更新 更多