-
Notifications
You must be signed in to change notification settings - Fork 2
TTY not defined when Stdio::piped() #29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
See https://cs.opensource.google/go/go/+/refs/tags/go1.24.0:src/os/exec/exec.go;l=574 as well as |
This does show there's a problem with `Stdio::piped()` in Rust, though. See #29 for details.
This does show there's a problem with `Stdio::piped()` in Rust, though. See #29 for details.
Works around #29 with an explicit color choice.
Works around #29 with an explicit color choice.
We can create a PTY in nix with The problem in either case is not being able to separate |
Something like this does work: let (pty, pts) =
pty_process::blocking::open().map_err(|err| akv_cli::Error::new(ErrorKind::Io, err))?;
let mut args = self.args.iter();
let program = args.next().ok_or_else(|| {
akv_cli::Error::with_message(ErrorKind::InvalidData, "command required")
})?;
let mut cmd = pty_process::blocking::Command::new(program).args(args);
// If stdout or stderr is already redirected, redirect the same streams for the PTY.
if !std::io::stdout().is_terminal() {
cmd = cmd.stdout(std::io::stdout());
}
if !std::io::stderr().is_terminal() {
cmd = cmd.stderr(std::io::stderr());
}
let mut process = cmd
.spawn(pts)
.map_err(|err| akv_cli::Error::new(ErrorKind::Io, err))?;
let reader = BufReader::new(pty);
let mut lines = reader.lines();
while let Some(Ok(line)) = lines.next() {
let masked = mask_secrets(&line, &secrets);
println!("{masked}");
} But there doesn't seem to be any good cross-platform PTY support. Out of somewhat active, well-downloaded crates, What I really want is something that just creates a PTY. For POSIX - optimization on linux to use It's a bit more involved on Windows, but still pretty straight-forward. Indeed, Windows does require preparing the child process to use a PTY, but it looks like we can do that if we target Thus, I could create a crate that just allocates a PTY and perhaps provides a helper on Thus, I don't need to write yet another process abstraction. And because I'm using a PTY, I really don't need async from |
printenv
was incorrectly writing VT sequences unconditionally, but when switching toanstream::println!()
andanstream::eprintln!()
color was no longer emitted. This is because the piped IO handles don't inherit (obviously) the FD soIsTerminal::is_terminal()
returnsfalse
.There are some crates out there like https://github.com/dtolnay/faketty that create a PTY, which might also help solve #22 better and, perhaps, is how Go's
os/exec
package is making all this work inop
.The text was updated successfully, but these errors were encountered: