From 37e38d17226a27978b5f890a5078ab755850e6d5 Mon Sep 17 00:00:00 2001 From: daniel fusser Date: Mon, 17 Aug 2026 22:51:30 +0200 Subject: [PATCH] fix tmux auto-attach spawning nested clients and blocking detach Two problems made the auto-attach loop: $TMUX was the only nesting guard, and it is trivially lost - sudo -i, env -i, ssh, and dropbear all hand back an interactive tty shell with it unset, so a shell below tmux would start another tmux. The guard also never checked for a login shell, so anything spawning `$SHELL -i` (fzf-tmux, file-manager shell escapes, editor :sh) dragged in a whole tmux client and a fresh grouped session. Now guarded on a login shell with stdin and stdout both a terminal, a $TERM that can host tmux, and an exported $TMUX_AUTOSTART that survives into panes and into nested shells that strip $TMUX. detach-on-destroy was off while the per-client sessions set destroy-unattached on. Those fight: detaching destroys the session, and off means the client is then switched to the most recently active remaining session instead of being allowed to leave - so detach put you back into "main". Restored to on, which is also the default. Co-Authored-By: Claude Opus 5 --- mksh/mkshrc | 14 +++++++++++++- tmux/tmux.conf | 5 ++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/mksh/mkshrc b/mksh/mkshrc index cc4967b..198f6d0 100644 --- a/mksh/mkshrc +++ b/mksh/mkshrc @@ -220,8 +220,20 @@ PS4='[$EPOCHREALTIME] '; PS1='#'; (( USER_ID )) && PS1='→'; PS1=$'\001\r''${| # grants each connection its own session grouped with "main" (shared panes, # independent window navigation). No -exec, so if tmux is missing or # exits/crashes for any reason, this shell just continues normally. +# +# Guards, in order: interactive; stdin and stdout are both a terminal; not +# already inside tmux; not below a tmux we started ($TMUX_AUTOSTART survives +# into panes and into nested shells that strip $TMUX, e.g. sudo -i, env -i, +# ssh, dropbear); login shell only, so tools that spawn `$SHELL -i` (fzf-tmux, +# file-manager shell escapes, editor :sh) don't drag in a whole tmux client; +# terminal can actually host tmux; tmux is installed. tmuxbin=$(\\builtin whence -p tmux 2>/dev/null) -if [[ $- = *i* ]] && [[ -t 0 ]] && [[ -z $TMUX ]] && [[ -n $tmuxbin ]]; then +if [[ $- = *i* ]] && [[ -t 0 ]] && [[ -t 1 ]] \ + && [[ -z $TMUX ]] && [[ -z $TMUX_AUTOSTART ]] \ + && [[ $0 = -* ]] \ + && [[ $TERM != dumb && $TERM != linux ]] \ + && [[ -n $tmuxbin ]]; then + \\builtin export TMUX_AUTOSTART=1 "$tmuxbin" fi unset tmuxbin diff --git a/tmux/tmux.conf b/tmux/tmux.conf index 3f1a75b..0662e00 100644 --- a/tmux/tmux.conf +++ b/tmux/tmux.conf @@ -2,7 +2,10 @@ # set-option -g default-shell /bin/mksh set-option -g focus-events on set -s escape-time 0 -set -g detach-on-destroy off +# Must stay `on` (the default): the per-client sessions below set +# destroy-unattached, so with `off` a detach would destroy the session and then +# punt the client into "main" instead of letting it leave. +set -g detach-on-destroy on set -g destroy-unattached off # bare `tmux` (no subcommand, e.g. from mkshrc's auto-attach) gets its own