rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
98.58k stars 12.74k forks source link

More verbose impl fmt::Debug for process::Command #42200

Closed lukaslueg closed 1 year ago

lukaslueg commented 7 years ago

impl fmt::Debug for process::Command currently only outputs the program and it's arguments. It should also output the environment variables and the current path, as set by .env(), .envs() and .current_dir(). This would help with figuring out what's going on :-)

Mark-Simulacrum commented 7 years ago

We also currently have no way to extract most of this information without utilizing Debug, so out of tree implementations can't be implemented.

zackmdavis commented 7 years ago

It should also output the environment variables and the current path, as set by .env(), .envs() and .current_dir()

Would/should this be the specific additions to the environment set by .env(), or the actual environment? The most straightforward implementation of this (debug-printing the individual fields of the internal Command struct) seems to do the latter.

That is, this patch (in src/libstd/sys/unix/process/process_common.rs)—

 impl fmt::Debug for Command {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "{:?}", self.program)?;
-        for arg in &self.args {
-            write!(f, " {:?}", arg)?;
-        }
-        Ok(())
+        f.debug_struct("Command")
+            .field("program", &self.program)
+            .field("args", &self.args)
+            .field("env", &self.env)
+            .field("argv", &self.argv)
+            .field("envp", &self.envp)
+            .field("cwd", &self.cwd)
+            .field("uid", &self.uid)
+            .field("gid", &self.gid)
+            .field("saw_nul", &self.saw_nul)
+            .field("stdin", &self.stdin)
+            .field("stdout", &self.stdout)
+            .field("stderr", &self.stderr)
+            .finish()
     }
 }

results in program behavior like this (scroll right to see the very bulky output; Debug should be verbose, but how verbose is too verbose??):

$ cat scratch.rs 
use std::process::Command;

fn main() {
    let mut cmd = Command::new("rustc");
    cmd.arg("--help");
    cmd.env("RUSTC_LOG", "debug");
    println!("{:?}", cmd);
}
$ ./build/x86_64-unknown-linux-gnu/stage1/bin/rustc scratch.rs 
$ ./scratch 
Command { program: "rustc", args: ["--help"], env: Some({"USER": (6, "USER=ubuntu"), "LS_COLORS": (7, "LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.axa=00;36:*.oga=00;36:*.spx=00;36:*.xspf=00;36:"), "XDG_SESSION_ID": (0, "XDG_SESSION_ID=1"), "SSH_AUTH_SOCK": (8, "SSH_AUTH_SOCK=/tmp/ssh-Lx51viZbnp/agent.1542"), "LOGNAME": (15, "LOGNAME=ubuntu"), "LESSOPEN": (17, "LESSOPEN=| /usr/bin/lesspipe %s"), "TERM": (1, "TERM=xterm"), "PWD": (11, "PWD=/home/ubuntu/rust"), "SHELL": (2, "SHELL=/bin/bash"), "LANG": (12, "LANG=en_US.UTF-8"), "SSH_TTY": (5, "SSH_TTY=/dev/pts/0"), "OLDPWD": (4, "OLDPWD=/home/ubuntu/rust/src"), "RUSTC_LOG": (21, "RUSTC_LOG=debug"), "SSH_CLIENT": (3, "SSH_CLIENT=99.113.185.154 58813 22"), "SHLVL": (13, "SHLVL=1"), "MAIL": (9, "MAIL=/var/mail/ubuntu"), "HOME": (14, "HOME=/home/ubuntu"), "_": (20, "_=./scratch"), "LESSCLOSE": (19, "LESSCLOSE=/usr/bin/lesspipe %s %s"), "XDG_RUNTIME_DIR": (18, "XDG_RUNTIME_DIR=/run/user/1000"), "SSH_CONNECTION": (16, "SSH_CONNECTION=99.113.185.154 58813 172.31.13.178 22"), "PATH": (10, "PATH=/home/ubuntu/.cargo/bin:/home/ubuntu/cmake-3.6.2-Linux-x86_64/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games")}), argv: [0x7fdafd01c008, 0x7fdafd01c010, 0x0], envp: Some([0x7fdafd01b140, 0x7fdafd025100, 0x7fdafd025110, 0x7fdafd01d090, 0x7fdafd01b080, 0x7fdafd01b0a0, 0x7fdafd025050, 0x7fdafd02dc00, 0x7fdafd01d0c0, 0x7fdafd01b0c0, 0x7fdafd0360a0, 0x7fdafd01b160, 0x7fdafd01b0e0, 0x7fdafd01c050, 0x7fdafd01b180, 0x7fdafd0250a0, 0x7fdafd026040, 0x7fdafd01b1a0, 0x7fdafd01b100, 0x7fdafd01d060, 0x7fdafd0250d0, 0x7fdafd025010, 0x0]), cwd: None, uid: None, gid: None, saw_nul: false, stdin: None, stdout: None, stderr: None }
lukaslueg commented 7 years ago

I'd be fine with the verbose output. The debug output is only meant for debug purposes and generating the full environment saves us from oh-that's-why-it's-not-working-this-stupid-thing moments

dtolnay commented 6 years ago

Seems reasonable. I would be ready to consider a PR implementing this.

steveklabnik commented 4 years ago

Triage: no changes here. I've actually wanted this too, but don't have the bandwidth to work on it, personally.