-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Description
I'm experiencing some odd behavior with ANSI codes and std::process::Command
. The ANSI codes render differently after having executed a command.
- In Git Bash using
\u{1b}[2m
(gray/dim) does not render at all, which is understanble as it might not be supported. However, after executing some command, then it renders correctly. - On the other hand, in CMD and PowerShell, then after running some command, then the ANSI codes appear literally in the output. (Which is the actual issue.)
The command being executed seem to be important, as changing it either results in the issue being triggered or no change at all.
Both spawn() + wait()
and status()
behave the same. Whereas output()
does not trigger the issue. So I'm assuming the command is somehow able to affect the inherited stdin/stdout/stderr, causing the issue to persist after the command has finished.
Git Bash
It's understandable that some ANSI code might not be supported by my terminal. But it's quite odd, that executing some command using std::process::Command
, results in it rendering correctly after.
CMD
However, the real issue is in CMD (and PowerShell), where every ANSI code renders literally in the output, after having executed some command.
Minimal, Reproducible Example
I also tried using the clicolors-control crate to enable/disable ANSI colors. However the issue still persists, and I originally submitted the issue there earlier mitsuhiko/clicolors-control#15.
use std::process::Command;
fn main() {
println!("Foo \u{1b}[36mBar\u{1b}[0m Baz"); // Cyan
println!("Foo \u{1b}[2mBar\u{1b}[0m Baz <- Not colored"); // Dim
println!("Foo \u{1b}[31mBar\u{1b}[0m Baz"); // Red
println!();
// ANSI codes render incorrectly if any of these commands are executed
Command::new("git").arg("log").status().unwrap();
// Command::new("git").arg("diff").status().unwrap();
// However, ANSI codes are not affected if any of these commands are executed
// Command::new("git").arg("--version").status().unwrap();
// Command::new("cargo").arg("--version").status().unwrap();
// Command::new("cargo").arg("build").status().unwrap();
println!();
println!("Foo \u{1b}[36mBar\u{1b}[0m Baz"); // Cyan
println!("Foo \u{1b}[2mBar\u{1b}[0m Baz"); // Dim
println!("Foo \u{1b}[31mBar\u{1b}[0m Baz"); // Red
println!();
}
Python
I thought it might be my terminal being weird. So I test the equivalent in Python, and it rendered correctly.
from subprocess import run
print("Foo \u001b[36mBar\u001b[0m Baz") # Cyan
print("Foo \u001b[2mBar\u001b[0m Baz") # Dim
print("Foo \u001b[31mBar\u001b[0m Baz") # Red
print()
run(["git", "log"])
print()
print("Foo \u001b[36mBar\u001b[0m Baz") # Cyan
print("Foo \u001b[2mBar\u001b[0m Baz") # Dim
print("Foo \u001b[31mBar\u001b[0m Baz") # Red
I've tested in both debug and release mode, as well as stable and nightly. The issue remains the same.
$ rustc --version --verbose
rustc 1.41.0 (5e1a79984 2020-01-27)
binary: rustc
commit-hash: 5e1a799842ba6ed4a57e91f7ab9435947482f7d8
commit-date: 2020-01-27
host: x86_64-pc-windows-msvc
release: 1.41.0
LLVM version: 9.0
$ cargo --version --verbose
cargo 1.41.0 (626f0f40e 2019-12-03)
release: 1.41.0
commit-hash: 626f0f40efd32e6b3dbade50cd53fdfaa08446ba
commit-date: 2019-12-03