下面的测试尝试运行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中完成这项工作?
答案 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!');
}