ssh - 如何防止在新的登录 shell 中嵌套 tmux 会话?
问题描述
几乎所有在 shell 启动时设置 tmux 运行的解决方案(1、2 )都依赖于一些环境变量,例如等。但是当我们启动一个登录 shell 时,例如 by ,所有变量都被清除,除了. 所以我们可以依靠来避免启动嵌套会话。假设默认设置是,我们设置以识别我们处于 TMUX 会话中。这适用于本地登录。$TMUX
$TERM
su -
$TERM
$TERM
$TERM
xterm
screen
.tmux.conf
现在,两台机器 A 和 B 使用相同的规则来控制嵌套会话,我们在机器 A 上的 tmux 会话中。当我们ssh
从 A 远程登录(通过)到 B 时,tmux 会话不会在 B 上启动,因为$TERM
已经设置为screen
.
那么,有没有办法在不依赖环境变量的情况下找出我们已经在 tmux 会话中?
PS:
我发布了一个解决方法作为我用来实现上述行为的答案。但是更准确和更好的方法,例如可以使用 tmux 命令工作的方法,将不胜感激。
解决方案
该解决方案的工作原理是确定当前终端是否连接到在同一台机器上运行的 tmux 服务器。为了找出连接,我们将使用伪终端对和I/O 统计破解。
但是,如果/proc
fs 或/dev
文件不能被用户读取/写入,它可能会失败。例如,如果 tmux 服务器是由 root 用户启动的,非 root 用户将无法找到它。
此外,如果 tmux 服务器在我们尝试向其写入零的同时从其他来源接收数据,我们可能会得到误报。
将其放在.bashrc
您想要的其他 shell 启动文件的末尾:
# ~/.bashrc
# don't waste time if $TMUX environemnt variable is set
[ -z $TMUX ] || return
# don't start a tmux session if current shell is not connected to a terminal
pts=$(tty) || return
# find out processes connected to master pseudoterminal
for ptm in $(fuser /dev/ptmx 2>/dev/null)
do
# ignore process if it's not a tmux server
grep -q tmux /proc/$ptm/comm || continue
# number of bytes already read by tmux server
rchar_old=$(awk '/rchar/ {print $2}' /proc/$ptm/io)
# write out 1000 bytes to current slave pseudoterminal terminal
dd bs=1 count=1000 if=/dev/zero of=$pts &>/dev/null
# read number of bytes again and find difference
diff=$(( $(awk '/rchar/ {print $2}' /proc/$ptm/io) - rchar_old ))
# if it equals 1000, current terminal is connected to tmux server
# however diff comes greater than 1000 most of the times
[ $diff -ge 1000 ] && return
done
# start or attach to a tmux session
echo 'Press any key to interrupt tmux session.'
read -st1 key && return
# connect to a detached session if exists for current user
session=($(tmux list-sessions 2>/dev/null | sed -n '/(attached)/!s/:.*r//p'))
[ -z $session ] || exec tmux a -t ${session[0]}
# start a new session after all
exec tmux
推荐阅读
- java - 当我使用 -jar 启动我的应用程序时,h2 数据库是空的?
- snowflake-cloud-data-platform - Snowflake 上的 Data Vault - load_datetime 属性应该使用什么时间戳数据类型
- .net - 使用 graphclient 获取扩展的附加属性
- r - R:改变图中点的大小
- android - Google Play:为部分国家/地区设置介绍性优惠
- database - 如何从 laravel 的 api 正文中获取属性?
- python - 如何在 Python 中将输出定向到文件以允许排序
- javascript - React Native:如果大于宽度百分比,则截断文本
- c++ - 构造函数不能被重新声明
- java - 如何在给定时间内多次调用方法java