@@ -164,12 +164,22 @@ fn render_init(shell: Shell) -> &'static str {
164164 if [[ -n "${BASH_VERSION:-}" ]]; then
165165 exec atuin pty-proxy --shell "$BASH"
166166 elif [[ -n "${ZSH_VERSION:-}" ]]; then
167- # Prefer ZSH_ARGZERO (zsh 5.3+) — it preserves the path zsh was
168- # invoked with — and fall back to PATH lookup otherwise. Login shells
169- # set argv[0] to "-zsh", and ZSH_ARGZERO keeps that leading dash, so
170- # strip it (${var#-}) before passing the path along.
171- _atuin_pty_proxy_zsh="${ZSH_ARGZERO:-$(command -v zsh)}"
172- exec atuin pty-proxy --shell "${_atuin_pty_proxy_zsh#-}"
167+ # Resolve zsh to the same executable that launched this init script.
168+ # ZSH_ARGZERO preserves argv0, including the leading dash used by login
169+ # shells, so normalize it before choosing a shell path.
170+ _atuin_pty_proxy_zsh_argv0="${ZSH_ARGZERO:-zsh}"
171+ _atuin_pty_proxy_zsh_argv0="${_atuin_pty_proxy_zsh_argv0#-}"
172+ if [[ "$_atuin_pty_proxy_zsh_argv0" == */* ]]; then
173+ # argv0 already contains a path, so it identifies the spawned zsh.
174+ _atuin_pty_proxy_shell="$_atuin_pty_proxy_zsh_argv0"
175+ elif [[ -f "${SHELL:-}" ]] && [[ -x "${SHELL:-}" ]] && [[ "${SHELL##*/}" == "$_atuin_pty_proxy_zsh_argv0" ]]; then
176+ # Bare argv0: prefer the matching login shell path over PATH lookup.
177+ _atuin_pty_proxy_shell="$SHELL"
178+ else
179+ # Last resort: resolve the bare shell name from PATH.
180+ _atuin_pty_proxy_shell="$(command -v "$_atuin_pty_proxy_zsh_argv0")"
181+ fi
182+ exec atuin pty-proxy --shell "$_atuin_pty_proxy_shell"
173183 else
174184 exec atuin pty-proxy
175185 fi
@@ -252,10 +262,23 @@ mod tests {
252262 fn init_scripts_forward_shell_path ( ) {
253263 let posix = render_init ( Shell :: Bash ) ;
254264 assert ! ( posix. contains( r#"exec atuin pty-proxy --shell "$BASH""# ) ) ;
255- // zsh: capture ZSH_ARGZERO (with PATH fallback), then strip the
256- // leading dash present on login shells before forwarding the path.
257- assert ! ( posix. contains( r#"_atuin_pty_proxy_zsh="${ZSH_ARGZERO:-$(command -v zsh)}""# ) ) ;
258- assert ! ( posix. contains( r#"exec atuin pty-proxy --shell "${_atuin_pty_proxy_zsh#-}""# ) ) ;
265+ // zsh: capture ZSH_ARGZERO, strip the leading dash present on login
266+ // shells, and resolve bare shell names to the spawning shell before
267+ // forwarding the path.
268+ assert ! ( posix. contains( r#"_atuin_pty_proxy_zsh_argv0="${ZSH_ARGZERO:-zsh}""# ) ) ;
269+ assert ! ( posix. contains( r#"_atuin_pty_proxy_zsh_argv0="${_atuin_pty_proxy_zsh_argv0#-}""# ) ) ;
270+ assert ! ( posix. contains( r#"if [[ "$_atuin_pty_proxy_zsh_argv0" == */* ]]; then"# ) ) ;
271+ assert ! ( posix. contains( r#"_atuin_pty_proxy_shell="$_atuin_pty_proxy_zsh_argv0""# ) ) ;
272+ assert ! ( posix. contains(
273+ r#"elif [[ -f "${SHELL:-}" ]] && [[ -x "${SHELL:-}" ]] && [[ "${SHELL##*/}" == "$_atuin_pty_proxy_zsh_argv0" ]]; then"#
274+ ) ) ;
275+ assert ! ( posix. contains( r#"_atuin_pty_proxy_shell="$SHELL""# ) ) ;
276+ assert ! (
277+ posix. contains(
278+ r#"_atuin_pty_proxy_shell="$(command -v "$_atuin_pty_proxy_zsh_argv0")""#
279+ )
280+ ) ;
281+ assert ! ( posix. contains( r#"exec atuin pty-proxy --shell "$_atuin_pty_proxy_shell""# ) ) ;
259282
260283 let fish = render_init ( Shell :: Fish ) ;
261284 assert ! ( fish. contains( "exec atuin pty-proxy --shell (status fish-path)" ) ) ;
0 commit comments