How do you run an interactive process in Dart?
https://stackoverflow.com/questions/12682269/how-do-you-run-an-interactive-process-in-dart
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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); }; } |
The following CoffeeScript function (using nodejs I/O) works:
1 2 3 4 5 6 | shell = (cmd, opts, callback) -> process.stdin.pause() child = spawn cmd, opts, customFds: [0, 1, 2] child. on 'exit' , (code) -> process.stdin.resume() callback code |
How can I make this work in Dart?
answer;
John has a good example about how to look at user input. But doesn't answer your original question. Unfortunately your question doesn't fit with how Dart operates. The two examples you have, the Dart version and CoffeeScript/Node.js version, do two completely different things.
In your CoffeeScript version, the spawn command is actually creating a new process and then passing execution over to that new process. Basically you're program is not interactively communicating with the process, rather your user is interacting with the spawned process.
In Dart it is different, your program is interacting with the spawned process. It is not passing off execution to the new process. Basically what you are doing is piping the input/output to and from the new process to your program itself. Since your program doesn't have a 'window height' from the terminal, it passes all the information at once. What you're doing in dart is almost equivalent to:
less /etc/mime.types | cat
You can use Process.start() to interactively communicate with processes. But it is your program which is interactively communicating with the process, not the user. Thus you can write a dart program which will launch and automatically play 'zork' or 'adventure' for instance, or log into a remote server by looking at the prompts from process's output.
However, at current there is no way to simply pass execution to the spawned process. If you want to communicate the process output to a user, and then also take user input and send it back to a process it involves an additional layer. And even then, not all programs (such as less) behave the same as they do when launched from a shell environment.
I planned to include some sample code with the above answer, however at the moment there appears to be a bug preventing output from a process from being read interactively. It looks like the buffers aren't being flushed by the process until after the process terminates the streams. Waiting on dartbug.com/5607 and then I will post the code :) – Matt B Oct 2 '12 at 18:27
Thank you for a great explanation (and the code you posted at issue 5607), I no longer need to keep banging my head against a wall :-) – Stuart Rackham Oct 2 '12 at 20:39
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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!' ); } |
【推荐】2025 HarmonyOS 鸿蒙创新赛正式启动,百万大奖等你挑战
【推荐】博客园的心动:当一群程序员决定开源共建一个真诚相亲平台
【推荐】开源 Linux 服务器运维管理面板 1Panel V2 版本正式发布
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步