Dart 不缓冲进程标准输出(告诉进程它正在从终端运行)

问题描述 投票:0回答:3

我正在尝试在 dart 中运行二进制文件宽度 Process.start 并将其输出重定向到 stdout 并将 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);
  });
}

问题是它仅在进程终止后刷新进程的标准输出。

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

我如何告诉进程它正在从终端运行?

我这个项目的目标是在 web 应用程序中拥有一个终端,与后端运行的进程交互,因此它将在终端上运行,但进程显然不知道这一点。

linux dart buffer stdout stdin
3个回答
1
投票

我正在回答我自己的问题,以防有人发现这篇文章。

我最终在这个库的帮助下用nodejs编写了后端(https://www.npmjs.com/package/node-pty

但是我也找到了一个类似的 dart 库(https://pub.dev/packages/pty


0
投票

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);

0
投票

此代码从新进程重定向所有 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} ${child.stderr}',
  );
}
© www.soinside.com 2019 - 2024. All rights reserved.