1
1
mirror of https://github.com/wez/wezterm.git synced 2024-11-23 15:04:36 +03:00

ssh: allow chdir to fail when spawning via ssh. use login shell.

Similar to 3b9be25161, but relax for
the ssh session when assume_shell="Posix".

Augument how we run the shell in this case as well, so that we make
an effort to run it as a login shell.

refs: #2092
refs: #2076
This commit is contained in:
Wez Furlong 2022-06-16 09:11:15 -07:00
parent 479b1384bb
commit bb1465508b

View File

@ -226,27 +226,45 @@ impl RemoteSshDomain {
cmd: &CommandBuilder, cmd: &CommandBuilder,
env: &HashMap<String, String>, env: &HashMap<String, String>,
) -> anyhow::Result<String> { ) -> anyhow::Result<String> {
let mut env_cmd = vec!["env".to_string()]; // "Soft" chdir: if it doesn't exist then it doesn't matter
if let Some(dir) = dir { let cd_cmd = if let Some(dir) = dir {
env_cmd.push("-C".to_string()); format!("cd {};", shell_words::quote(&dir))
env_cmd.push(dir.clone());
} else if let Some(dir) = cmd.get_cwd() { } else if let Some(dir) = cmd.get_cwd() {
let dir = dir.to_str().context("converting cwd to string")?; let dir = dir.to_str().context("converting cwd to string")?;
env_cmd.push("-C".to_string()); format!("cd {};", shell_words::quote(&dir))
env_cmd.push(dir.to_string()); } else {
} String::new()
};
let mut env_cmd = vec!["env".to_string()];
for (k, v) in env { for (k, v) in env {
env_cmd.push(format!("{}={}", k, v)); env_cmd.push(format!("{}={}", k, v));
} }
let cmd = if cmd.is_default_prog() { let cmd = if cmd.is_default_prog() {
"$SHELL".to_string() // We'd like to spawn a login shell, but since we are invoking env
// we end up in a regular shell.
// This guff tries to find a reasonably portable way to execute
// the shell as a login shell.
// Per: <https://unix.stackexchange.com/a/666850/123914>
// the most portable way is to use perl, but in case perl is not
// installed, zsh, bash and ksh all support `exec -a`.
// Other shells may support `exec -a` but there isn't a simple
// way to test for them, so we assume that if we have one of those
// three that we can use it, otherwise we fall back to just running
// the shell directly.
let login_shell = "command -v perl > /dev/null && \
exec perl -e 'use File::Basename; $shell = basename($ENV{SHELL}); exec {$ENV{SHELL}} \"-$shell\"'; \
case \"$SHELL\" in */zsh|*/bash|*/ksh ) exec -a \"-$(basename $SHELL)\" $SHELL ;; esac ; \
exec $SHELL";
format!("$SHELL -c {}", shell_words::quote(login_shell))
} else { } else {
cmd.as_unix_command_line()? cmd.as_unix_command_line()?
}; };
Ok(shell_words::join(env_cmd) + " " + &cmd) Ok(cd_cmd + &shell_words::join(env_cmd) + " " + &cmd)
} }
let command_line = match (cmd.is_default_prog(), self.dom.assume_shell, command_dir) { let command_line = match (cmd.is_default_prog(), self.dom.assume_shell, command_dir) {