diff --git a/CHANGELOG.md b/CHANGELOG.md index 899ce8b..584bfe4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,13 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed + +- `SystemInfo` data type now includes two additional fields: `username` and + `shell`. The `username` field represents the name of the user running the + server process. The `shell` field points to the default shell associated with + the user running the server process + ### Fixed -- `distant client shell` will now choose between `/bin/sh` and `cmd.exe` as the - default shell based on the family returned by a system info request +- `distant client shell` will now use the default shell from system info, or + choose between `/bin/sh` and `cmd.exe` as the default shell based on the + family returned by a system info request - `distant client shell` properly terminates master pty when the shell exits, resolving the hanging that occurred for Windows `cmd.exe` and `powershell.exe` upon exit +- ssh launch with login shell now only uses `sh` when remote family is `unix` ## [0.18.0] - 2022-08-18 ### Changed diff --git a/distant-ssh2/src/lib.rs b/distant-ssh2/src/lib.rs index 2c66011..488f853 100644 --- a/distant-ssh2/src/lib.rs +++ b/distant-ssh2/src/lib.rs @@ -617,19 +617,18 @@ impl Ssh { .map_err(|x| io::Error::new(io::ErrorKind::InvalidInput, x))?, }); - // If we are using a login shell, we need to make the binary be sh - // so we can appropriately pipe into the login shell - let cmd = if opts.use_login_shell { - format!( + // If we are using a login shell, we need to make the binary be sh so we can appropriately + // pipe into the login shell. This is only available on unix. + let cmd = match family { + SshFamily::Unix if opts.use_login_shell => format!( "sh -c {}", shell_words::quote(&format!( "echo {} {} | $SHELL -l", opts.binary, args.join(" ") )) - ) - } else { - format!("{} {}", opts.binary, args.join(" ")) + ), + _ => format!("{} {}", opts.binary, args.join(" ")), }; // Spawn distant server and detach it so that we don't kill it when the diff --git a/src/cli/commands/client/shell.rs b/src/cli/commands/client/shell.rs index 4cd310d..3f741da 100644 --- a/src/cli/commands/client/shell.rs +++ b/src/cli/commands/client/shell.rs @@ -32,7 +32,7 @@ impl Shell { environment.insert("TERM".to_string(), "xterm-256color".to_string()); } - // Use provided shell, or determine remote operating system to pick a shell + // Use provided shell, use default shell, or determine remote operating system to pick a shell let cmd = match cmd.into() { Some(cmd) => cmd, None => { @@ -41,7 +41,12 @@ impl Shell { .system_info() .await .context("Failed to detect remote operating system")?; - if system_info.family.eq_ignore_ascii_case("windows") { + + // If system reports a default shell, use it, otherwise pick a default based on the + // operating system being windows or non-windows + if !system_info.shell.is_empty() { + system_info.shell + } else if system_info.family.eq_ignore_ascii_case("windows") { "cmd.exe".to_string() } else { "/bin/sh".to_string() diff --git a/tests/cli/action/system_info.rs b/tests/cli/action/system_info.rs index 40847a0..bf7c6ed 100644 --- a/tests/cli/action/system_info.rs +++ b/tests/cli/action/system_info.rs @@ -17,12 +17,20 @@ fn should_output_system_info(mut action_cmd: CtxCommand) { "Arch: {:?}\n", "Cwd: {:?}\n", "Path Sep: {:?}\n", + "Username: {:?}\n", + "Shell: {:?}\n", ), env::consts::FAMILY.to_string(), env::consts::OS.to_string(), env::consts::ARCH.to_string(), env::current_dir().unwrap_or_default(), std::path::MAIN_SEPARATOR, + whoami::username(), + if cfg!(windows) { + std::env::var("ComSpec").unwrap_or_else(|_| String::from("cmd.exe")) + } else { + std::env::var("SHELL").unwrap_or_else(|_| String::from("/bin/sh")) + } )) .stderr(""); } diff --git a/tests/cli/repl/system_info.rs b/tests/cli/repl/system_info.rs index 9a4a1e2..2dbf417 100644 --- a/tests/cli/repl/system_info.rs +++ b/tests/cli/repl/system_info.rs @@ -23,7 +23,13 @@ async fn should_support_json_system_info(mut json_repl: CtxCommand) { "os": env::consts::OS.to_string(), "arch": env::consts::ARCH.to_string(), "current_dir": env::current_dir().unwrap_or_default(), - "main_separator": std::path::MAIN_SEPARATOR, + "main_separator": std::path::MAIN_SEPARATOR.to_string(), + "username": whoami::username(), + "shell": if cfg!(windows) { + std::env::var("ComSpec").unwrap_or_else(|_| String::from("cmd.exe")) + } else { + std::env::var("SHELL").unwrap_or_else(|_| String::from("/bin/sh")) + } }) ); }