TMOUT必须同时满足整数、export导出、shell启动时加载三个硬条件才生效;仅写TMOUT=600无效,须用export TMOUT=600,且需防被覆盖、拼写错误或SSH心跳抢先断连。
TMOUT 不是设了就生效的开关,必须同时满足“整数 + export + 启动时加载”三个硬条件,否则 echo $TMOUT 一定为空。
为什么 TMOUT=600 写进 /etc/profile 却不生效
只写 TMOUT=600 是普通变量赋值,bash 不会拿它做超时判断;必须用 export TMOUT=600 才行。常见失效原因包括:
-
TMOUT值不是整数:比如写成TMOUT=10m、TMOUT=600.0或带空格的TMOUT = 600,shell 直接忽略 - 用户级文件覆盖系统级设置:若
~/.bashrc中有unset TMOUT或TMOUT=0,且该文件被 source 过,/etc/profile 的设置就被清掉了 - 图形终端(GNOME Terminal、Konsole)默认启动非登录 shell,
/etc/profile根本不加载——得改/etc/bash.bashrc(Debian/Ubuntu)或在终端设置里勾选“以登录 shell 方式运行命令” - 拼写错误:
tmout、TIMEOUT、TMOU全无效,变量名严格为TMOUT,大小写敏感,无下划线
如何让 TMOUT 对所有用户真正生效且防绕过
推荐统一走 /etc/profile.d/ 路径,比直接改 /etc/profile 更安全、易维护:
- 新建脚本:
sudo tee /etc/profile.d/autologout.sh <<'EOF'export TMOUT=1800readonly TMOUTEOF - 加执行权限:
sudo chmod +x /etc/profile.d/autologout.sh - 验证是否只读:
declare -p TMOUT输出中应含readonly字样 - 避免用户自行
unset TMOUT或TMOUT=0,但注意:一旦设为readonly,当前会话无法撤销,必须重新登录
SSH 连接断开早于 TMOUT?检查 ClientAliveInterval 是否抢跑了
SSH 层心跳检测(ClientAliveInterval + ClientAliveCountMax)优先级高于 shell 层 TMOUT。如果连接在设定时间前就断了,大概率是 SSH 先动手了:
CentOS Linux 7.9.2009
CentOS Linux 7.9.2009是传统CentOS Linux 7的最后主要版本,也是很多企业历史服务器中仍可能遇到的系统版本。它以稳定、兼容RHEL 7生态、文档丰富和软件支持广泛著称,曾长期用于Web服务、数据库、虚拟化节点和企业内部业务系统。不过CentOS Linux 7已于2024年6月30日停止维护,现在继续使用会面临安全补丁缺失风险。该版本更适合旧业务迁移、历史环境恢复或离线兼容性测试。
下载
- 确认
/etc/ssh/sshd_config中:ClientAliveInterval 420(7 分钟)和ClientAliveCountMax 2(最多空闲 14 分钟),总超时需大于TMOUT值(如TMOUT=600对应 10 分钟) - 修改后必须重启服务:
sudo systemctl restart sshd,仅 reload 不生效 - 测试方法:SSH 登录后执行
sleep 610,若 610 秒后才退出,说明是TMOUT在起作用;若不到 10 分钟就断,就是ClientAlive在干预 -
ClientAliveInterval 0表示禁用心跳,此时完全依赖TMOUT,但不推荐——网络假活跃(如笔记本休眠)会导致僵尸连接长期滞留
TMOUT 管不了的场景,别硬塞
TMOUT 只对交互式登录 shell 有效,以下情况它基本不参与:
- 后台命令持续输出(如
watch -n 1 date、tail -f /var/log/syslog)会不断重置计时器 -
sudo -i启动的新 shell 默认不继承父 shell 的TMOUT,除非显式配置env_reset白名单 -
tmux、screen、byobu等复用器会拦截输入事件,TMOUT失效,需单独配置其内部超时(如tmux set -g idle-timeout 1800) - 自动化脚本、cron 任务、systemd service 不受
TMOUT影响——它们本来就不该依赖交互式超时机制
真要保关键会话不中断,靠 TMOUT 不现实;该用密钥免密 + 连接池管理,或者换 mosh 应对网络抖动。
