用 exec 替换 tmux

用 exec 替换 tmux

我使用 tmux 一段时间了,我对它非常满意。因为我大多数时候都需要它,所以我将它设置为我的默认 shell(准确地说是 guake)。

这很好,我对此非常满意。

但有时,我需要退出 tmux 并拥有一个干净的 shell,但由于我默认使用 tmux,终止会话将导致稍后出现另一个 tmux。

所以,我的问题是:是否可以替换多路复用进程使用给定的外壳?

exec当然,类似的东西是行不通的,因为它取代了 tmux 内部的 shell,而不是 tmux 本身。

答案1

我不认为 tmux 能做到这一点。如果您了解 C 编程,那么修补应该很容易。

您可以做的一件事是从包装 shell 脚本调用 tmux,并让脚本决定是否退出。向包装器发送信号,告诉它在 tmux 退出时执行交互式 shell。这是包装器脚本的未经测试的概念验证:

export TMUX_PARENT_PID=$$
trap 'exec bash -i' USR1
tmux

~/.tmux.conf

update-environment DISPLAY WINDOWID SSH_ASKPASS SSH_AUTH_SOCK SSH_AGENT_PID SSH_CONNECTION TMUX_PARENT_PID

从 tmux 内部,分离后获得 shell 提示:

TMUX_PARENT_PID=$(tmux show-environment | sed -n 's/^TMUX_PARENT_PID=//p')
kill -USR1 $TMUX_PARENT_PID
tmux detach-client

答案2

如果 tmux 正在运行,则会设置环境变量 TMUX,因此通过将这样的行放入 bashrc 中,tmux 仍然是您的 shell。

但如果它已经在运行,bash 或其他 shell 会正常运行(不要使用 chsh 将 shell 设置为 tmux,这可能是一个问题)

if [[ ! -z ${TMUX} ]]; then
    // run tmux
    tmux "$@"
    exit 0
fi
// tmux is already running

答案3

我知道我迟到了几年,但在阅读了 @Gilles 的答案后,我花了一两个小时重新设计我的.profile文件以添加信号机制,我相信这可能会更好地回答最初的问题(在正文中,而不是标题中):

# Start tmux:
if [ -n "$(type tmux 2> /dev/null)" ] && [ -z "$TMUX" ]; then
    # Configure a signal handler to allow the tmux session to toggle the exit flag:
    export EXIT_FLAG=1
    export TMUX_PARENT_PID=$$
    trap 'EXIT_FLAG=$(($EXIT_FLAG ^ 1))' USR1

    # Start tmux:
    tmux new-session -s "shell$$" "TMUX_PARENT_PID=$$ $SHELL -l"

    # Exit, assuming the exit flag has not been flipped:
    if [ "x$EXIT_FLAG" == "x1" ]; then
        exit
    fi

    # Otherwise, cleanup the environment:
    unset EXIT_FLAG
    unset TMUX_PARENT_PID
    unset TMUX
fi

在 my 中使用此命令.profile,所有 shell 将默认启动 tmux,并且也将随 tmux 退出。如果我希望 shell 在退出 tmux 后继续存在,我只需要kill -s USR1 $TMUX_PARENT_ID在 run 之前运行exit,shell 就不会退出。

请注意,kill ...上面的命令实际上会切换EXIT_FLAG变量,因此kill ...连续运行两次实际上会自行取消。

相关内容