Ruby捕获$stdout后输出丢失bash终端颜色的问题
终端输出捕获后丢失颜色代码的问题
直接输出正常显示颜色
直接执行Rails生成器命令时,终端能正常渲染ANSI颜色代码,例如“create”字样显示为绿色:
RailsAppGenerator::AppGenerator.start(opts, destination_root: destination_root)

捕获输出后丢失颜色
当通过自定义方法捕获输出到变量,再写回标准输出时,终端不再显示颜色:
capture_console do RailsAppGenerator::AppGenerator.start(opts, destination_root: destination_root) end def capture_console $stdout = StringIO.new yield @console_output = $stdout.string $stdout.close STDOUT.puts @console_output ensure $stdout = STDOUT # save_stdout end
问题原因
Rails生成器这类命令行工具会检测输出目标是否为TTY终端。当输出到StringIO(非TTY环境)时,工具会自动禁用颜色输出,避免在不支持ANSI代码的环境中输出乱码。
解决方案
1. 强制开启颜色输出
直接给生成器传递强制颜色的参数,或通过环境变量开启:
# 方法A:通过参数强制开启 capture_console do RailsAppGenerator::AppGenerator.start(opts.merge(color: true), destination_root: destination_root) end # 方法B:通过环境变量开启 ENV['RAILS_COLOR'] = '1' capture_console do RailsAppGenerator::AppGenerator.start(opts, destination_root: destination_root) end
2. 让StringIO模拟TTY环境
修改捕获方法,让StringIO对象伪装成TTY终端,欺骗生成器输出颜色代码:
def capture_console original_stdout = $stdout $stdout = StringIO.new # 添加tty?方法返回true,模拟终端环境 $stdout.define_singleton_method(:tty?) { true } yield @console_output = $stdout.string ensure $stdout.close STDOUT.puts @console_output $stdout = original_stdout # 恢复原始标准输出 end
内容的提问来源于stack exchange,提问作者David Cruwys
相关产品推荐
相关产品推荐

