You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dart中Process.start执行Appwrite初始化时如何获取完整stdout输出

Dart Process.start 完整获取stdout输出的解决方案

问题场景

使用Dart的Process.start自动化创建Appwrite项目时,stdout会以分块形式返回,部分块还包含终端刷新产生的重复内容,无法直接拿到完整输出。测试代码如下:

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

void main(List<String> arguments) async {
  Process process = await Process.start(
    'appwrite',
    ['init', 'project'],
  );

  process.stdout.listen((event) {
    String s = utf8.decode(event);
    print(s);
    if (s.contains('Create a new Appwrite project')) {
      process.stdin.writeln();
    }
  });

  process.stderr.listen((event) {
    String s = utf8.decode(event);
    print(s);
  });
}

输出截图:
输出截图

解决方案

1. 流式场景(需实时交互):用缓冲区收集所有输出

Process.start是流式API,操作系统会按缓冲区大小分块传输数据,必须将所有分块内容收集到缓冲区中才能获取完整输出。同时,检查交互触发条件时要基于完整缓冲区内容,避免因目标字符串被拆分到多个块中而错过触发时机。

示例代码:

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

void main(List<String> arguments) async {
  final process = await Process.start('appwrite', ['init', 'project']);
  
  // 收集完整stdout内容的缓冲区
  final stdoutBuffer = StringBuffer();
  final utf8Decoder = Utf8Decoder();
  
  // 监听stdout流,收集所有分块内容
  process.stdout.listen((bytes) {
    final chunk = utf8Decoder.convert(bytes);
    stdoutBuffer.write(chunk);
    print(chunk); // 实时打印输出,可选
    
    // 检查完整缓冲区是否包含目标字符串,触发交互
    if (stdoutBuffer.toString().contains('Create a new Appwrite project')) {
      process.stdin.writeln();
    }
  });
  
  // 监听stderr输出
  process.stderr.listen((bytes) => print(utf8.decode(bytes)));
  
  // 等待进程结束
  final exitCode = await process.exitCode;
  print('进程退出码: $exitCode');
  
  // 获取完整的stdout内容
  final fullStdout = stdoutBuffer.toString();
  print('\n=== 完整输出内容 ===');
  print(fullStdout);
  
  // 可选:过滤终端ANSI控制字符(移除刷新/格式控制内容)
  final cleanOutput = fullStdout.replaceAll(RegExp(r'\x1B\[[0-?]*[ -/]*[@-~]'), '');
  print('\n=== 清理后输出 ===');
  print(cleanOutput);
}

2. 非流式场景(无需实时交互):使用Process.run

如果不需要实时处理进程输出,只是想一次性获取完整结果,可以用Process.run替代Process.start,该方法会等待进程执行完毕后返回所有输出内容。

示例代码:

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

void main(List<String> arguments) async {
  // 执行命令,传入所需的输入内容
  final result = await Process.run(
    'appwrite',
    ['init', 'project'],
    stdin: utf8.encode('\n'), // 模拟用户输入回车
    runInShell: true, // 部分环境下需要启用shell执行
  );
  
  print('=== 标准输出 ===');
  print(result.stdout);
  print('\n=== 标准错误 ===');
  print(result.stderr);
  print('\n退出码: ${result.exitCode}');
}

说明

出现分块/重复内容的原因是Appwrite CLI使用了终端交互库,会输出ANSI控制字符来刷新终端界面,这些控制字符会被当作输出内容返回。如果需要纯净的输出,可以用正则表达式过滤掉这些控制字符(如上述示例中的cleanOutput部分)。

内容的提问来源于stack exchange,提问作者Develocode 777

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 14:00:49