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

Raku如何避免调用tree命令时出现Malformed UTF-8错误

问题根因
  • Raku 的 run/shell 调用启动子进程时,不会加载 zsh 的交互配置,子进程继承的系统基础环境未设置 UTF-8 相关的 locale 变量,和你在终端直接运行命令的环境不一致
  • 你遇到的 Malformed UTF-8 报错,本质是 tree 在非 UTF-8 locale 下输出了非 UTF-8 编码的制表符(对应报错里的 ef b9 5c 非法字节序列)
  • 之前尝试的 utf8-c8 编码、临时文件重定向方案无效,是因为 tree 输出本身根本不是 UTF-8 编码序列,无论用什么编码读取原始字节都会触发解码错误
可直接运行的解决方案

方案1:直接强制 tree 输出 UTF-8 内容(推荐)

GNU tree 原生支持通过参数指定输出字符集,不需要修改全局环境变量:

my $proc = run( 'tree', '--du', '--charset=utf-8', :out);
# 读取时显式指定按UTF-8解码
$proc.out.slurp(:close, enc => 'utf8').say;

方案2:给子进程显式传入UTF-8 locale环境

如果你的 tree 版本不支持 --charset 参数,可以在调用时主动给子进程传入正确的环境变量,强制 tree 输出 UTF-8 内容:

# 克隆当前环境并补充UTF-8 locale配置
my %proc-env = %*ENV.clone;
%proc-env<LANG>  = 'en_US.UTF-8';
%proc-env<LC_ALL> = 'en_US.UTF-8';

my $proc = run( 'tree', '--du', :out, :env(%proc-env));
$proc.out.slurp(:close, enc => 'utf8').say;

可通过终端执行 locale -a 查询你系统上可用的UTF-8 locale名称,替换示例中的 en_US.UTF-8 即可。

修正后的临时文件方案

如果需要沿用之前的临时文件逻辑,需要同步修正两点:一是给 tree 调用显式传入UTF-8配置,二是打开文件时指定正确的编码:

shell( "LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 tree --du >> .temp.txt" );
# 打开文件时显式指定UTF-8编码,避免默认解码错误
my @lines = open(".temp.txt", enc => 'utf8').lines;
dd @lines;
注意事项
  • 不要使用 utf8-c8 编码参数,该编码仅用于处理合法UTF-8序列中夹杂少量非法字节的场景,对完全非UTF8的输入无效
  • 你之前在终端直接运行tree能正常输出,是因为zsh的交互配置已经设置了正确的locale变量,Raku调用的非交互子进程不会自动加载这些配置,必须显式指定

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.31 01:15:04