Terminal 在Rust中,如何使用颜色捕获流程输出?

Terminal 在Rust中,如何使用颜色捕获流程输出?,terminal,console,rust,tty,windows-console,Terminal,Console,Rust,Tty,Windows Console,我想从另一个进程(例如git status)捕获输出,对其进行处理,并使用所有样式(粗体、斜体、下划线)和颜色进行打印。对我来说,进一步处理字符串非常重要,我不想只打印它 在Unix世界中,我认为这可能涉及转义码,我不确定Windows世界,但这对我来说也很重要 我知道没有颜色怎么做: fn exec_git() -> String { let output = Command::new("git") .arg("status") .output()

我想从另一个进程(例如
git status
)捕获输出,对其进行处理,并使用所有样式(粗体、斜体、下划线)和颜色进行打印。对我来说,进一步处理
字符串
非常重要,我不想只打印它

在Unix世界中,我认为这可能涉及转义码,我不确定Windows世界,但这对我来说也很重要

我知道没有颜色怎么做:

fn exec_git() -> String {
    let output = Command::new("git")
        .arg("status")
        .output()
        .expect("failed to execute process");

    String::from_utf8_lossy(&output.stdout).into_owned()
}

也许我应该改用
spawn

您可以通过使用
git-c color.status=始终status

use std::process::Command;

fn main() {
    let output = Command::new("git")
        .arg("-c")
        .arg("color.status=always")
        .arg("status")
        .output()
        .expect("failed to execute process");

    let output = String::from_utf8_lossy(&output.stdout).into_owned();

    println!("{}", output);
}

这仅适用于
git状态
。对于更通用的解决方案,您必须检查程序文档并希望有一种强制彩色输出的方法,或者检查程序如何确定是否应输出颜色(例如检查
COLORTERM
环境变量)。

您的代码已经起作用了

use std::process::Command;

fn main() {
    let output = Command::new("ls")
        .args(&["-l", "--color"])
        .env("LS_COLORS", "rs=0:di=38;5;27:mh=44;38;5;15")
        .output()
        .expect("Failed to execute");

    let sout = String::from_utf8(output.stdout).expect("Not UTF-8");
    let serr = String::from_utf8(output.stderr).expect("Not UTF-8");

    println!("{}", sout);
    println!("{}", serr);
}
打印输出:

总数68
-rw-r--r--4根根部56158 Dec 23 00:00[0m[44;38;5;15货物锁[0m]
-rw-rw-r--4根根根2093年12月9日02:54[44;38;5;15mchargo.toml[0m
drwxr-xr-x 1根根根4096 Dec 30 15:24[38;5;27msrc[0m
drwxr-xr-x 1根根根4096 Dec 23 00:19[38;5;27m目标[0m
请注意,输出中散布着一堆垃圾(
[44;
[0m
,等等)。这些都是,终端仿真器会解释这些垃圾以更改以下文本的颜色

如果使用调试打印字符串,您将看到:

\u{1b}[0m\u{1b}[44;38;5;15mCargo.lock\u{1b}[0m
每个转义码都以一个
ESC
\u{1b}
)开头,后跟实际命令。您必须解析这些转义码,以便在执行任何处理时忽略它们


Windows不使用转义码(虽然?),而是直接使用程序。输出中没有任何颜色指示。

您是否在寻找一种方法来愚弄git,使其认为它正在输出到终端(从而使其输出着色)或者,您是否满足于只向git传递一个标志/配置,强制它使用颜色而不依赖终端检测?愚弄
git
似乎是个好主意。现在
git
检查流是否正确?(类似于libuv中的
if(uv\u guess\u handle(1)=uv TTY)
)好的-让我们假设我会愚弄它(不知道如何愚弄它,但我迟早会解决这个问题)。然后我的输出将包含转义码,打印它们将为最终输出着色?如果你设法愚弄git,是的,你的输出应该着色(如果它在终端上着色),然而,这可能是最困难的选择,我不太确定你如何做到。好吧,这根本不能在控制台中的Windows上完成。@WojciechPolak我建议你用不同的标签问这个问题,可能是Windows控制台、控制台、终端。然后当你得到一个通用解决方案时,你可以发布另一个关于如何翻译的问题这个问题的要点并不是针对生锈,我敢打赌stackoverflow上有很多专家只监控特定的标签。