DART没有缓冲过程Stdout(告诉过程是从终端运行)

发布于 2025-01-27 12:34:11 字数 588 浏览 4 评论 0原文

我正在尝试运行一个二进制文件宽度过程。在DART中启动并将其输出将Stdout和Pipe STDIN重定向到该过程。

这是我的代码:

import 'dart:io';
import 'dart:convert';

main() async {
  Process.start('./test.bin', []).then((p) {
    p.stdout.listen((bytes) {
      stdout.add(bytes);
      stdout.flush();
    });
    stdin.pipe(p.stdin);
  });
}

问题在于,它仅在过程终止后才冲洗过程的Stdout。

在互联网上进行挖掘后,我发现了这一点:“这是由libc引起的,默认情况下,当未连接到终端时,它会将stdout int缓冲模式放置。”

我该如何告诉该过程是从终端运行的?

我对此项目的目标是在WebApp中具有与此过程在后端运行的该过程相互作用的终端,因此它将在一个终端,但这个过程显然没有意识到。

I'm trying to run a binary file width Process.start in dart and redirect its output the stdout and pipe stdin to the process.

Here is my code:

import 'dart:io';
import 'dart:convert';

main() async {
  Process.start('./test.bin', []).then((p) {
    p.stdout.listen((bytes) {
      stdout.add(bytes);
      stdout.flush();
    });
    stdin.pipe(p.stdin);
  });
}

The problem is that it only flushes the process's stdout after the process terminates.

After digging around on the internet I found this: "This is caused by libc which by default puts stdout int buffered mode when it is not connected to a terminal."

How could I tell the process that it is running from a terminal?

My goal with this project is to have a terminal in a webapp that interacts with this process running on the backend, so it will be running on a terminal but the process is obviously unaware of that.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

ι不睡觉的鱼゛ 2025-02-03 12:34:11

我要回答自己的问题,以防有人找到这篇文章。

我最终在此库的帮助下在nodejs上写了后端( https:https://www.npmjs 。

​//pub.dev/packages/pty )

I'm answering my own question in case anyone finds this post.

I ended up writing the backend in nodejs with the help of this library (https://www.npmjs.com/package/node-pty)

But I found a similar library for dart as well (https://pub.dev/packages/pty)

蘸点软妹酱 2025-02-03 12:34:11

在儿童过程管理的情况下,NodeJS更好。但是我认为您可以使用某些类型的缓冲区拆分来修复代码。划分的示例: -

var process = await Process.start(cmd, param,
        environment: env,
        includeParentEnvironment: true,
        runInShell: true,
        mode: ProcessStartMode.normal);
    Stream<String> readLine() => process.stdout
        .transform(utf8.decoder)
        .transform(const LineSplitter());
    readLine().listen(callback);
    var exitcode = await process.exitCode;
    print("Process Exit:- " + exitcode);

NodeJS is more better in case of child process management. But i think you can fix your code with use of some types buffer splitting. Example of Split by line:-

var process = await Process.start(cmd, param,
        environment: env,
        includeParentEnvironment: true,
        runInShell: true,
        mode: ProcessStartMode.normal);
    Stream<String> readLine() => process.stdout
        .transform(utf8.decoder)
        .transform(const LineSplitter());
    readLine().listen(callback);
    var exitcode = await process.exitCode;
    print("Process Exit:- " + exitcode);
孤千羽 2025-02-03 12:34:11

该代码将新过程中的所有STDIO流重定向。它有一些详细信息

  1. ,以检查终端的可用性,并在提供标准输入的情况下。
  2. 它关闭线模式,以便在接收Enter键之前,来自STDIO的数据不会被缓冲。

代码:

final child = await Process.start(command, args, runInShell: true);

if (stdin.hasTerminal) {
  stdin.lineMode = false;
  unawaited(stdin.pipe(child.stdin));
}
unawaited(child.stdout.pipe(stdout));
unawaited(child.stderr.pipe(stderr));

if (await child.exitCode != 0) {
  throw Exception(
    'Failed to execute $command ${args.join(' ')}: with code ${await child.exitCode}',
  );
}

This code redirects all stdio streams from a new process. It has a few details

  1. It checks for the availability of terminal and pipes the standard input if available.
  2. It switches the line mode off so that the data from stdio does not gets buffered before receiving the Enter key.

Code:

final child = await Process.start(command, args, runInShell: true);

if (stdin.hasTerminal) {
  stdin.lineMode = false;
  unawaited(stdin.pipe(child.stdin));
}
unawaited(child.stdout.pipe(stdout));
unawaited(child.stderr.pipe(stderr));

if (await child.exitCode != 0) {
  throw Exception(
    'Failed to execute $command ${args.join(' ')}: with code ${await child.exitCode}',
  );
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文