首页 新闻 会员 周边 捐助

两层ssh跳板机,ssh -t怎么停在跳板机了,不自动执行完退出

0
[已关闭问题] 关闭于 2025-12-26 07:59

是一个非常经典的 SSH TTY(终端)争夺问题。
简单直接的回答是:去掉 -t 参数,或者把 -t 改成 -T (大写)。
🤔 为什么会出现这个问题?
当你使用 ssh -t 时,你是在强制 SSH 分配一个 伪终端(Pseudo-TTY) 并将其锁定在当前会话上。
在两层跳板(A -> B -> C)的场景下:
1. 第一层(A -> B):你按下了回车,A 把你的键盘(stdin)和屏幕(stdout)通过 -t 强行挂载到了 B 上。
2. 第二层(B -> C):B 上的 SSH 命令试图通过 C 执行命令。
3. 卡住的原因:因为 -t 抢占了标准输入(stdin),导致第二层的 SSH 无法正常读取到“执行完命令就退出”的信号。C 以为你是一个交互式用户登录进来了,所以它把 Shell 丢给你后就挂起等待你输入命令,而不是执行完命令自动退出。



✅ 正确的解决方法
方案 1:去掉 -t (最推荐)
如果你只是执行命令,不需要交互式终端,完全不需要加 -t 。

# 错误:强制分配终端,导致卡住
ssh -t user@jump1 "ssh -t user@target 'your_command'"

# 正确:不加 -t,让命令执行完自动退出
ssh user@jump1 "ssh user@target 'your_command'"

方案 2:显式禁用终端(使用 -T )
如果你必须写脚本,为了防止本地环境干扰,可以显式禁用 TTY。

ssh -T user@jump1 "ssh -T user@target 'your_command'"

方案 3:如果必须使用 -t (极少数情况)
只有在你需要交互式操作(比如执行完命令后还要手动敲代码)时才用 -t 。但如果是两层跳板且想自动退出,必须使用 -tt (两个 t)来强制分配并立即释放。

# 强制分配终端,但执行完命令后强制关闭连接
ssh -tt user@jump1 "ssh -tt user@target 'your_command'"

注意: -tt  通常用于自动化脚本中,当目标命令不需要交互但又必须分配 TTY 时(例如运行  sudo  或  docker exec -it )。

🛠️ 针对你之前代码的修改建议
结合你之前的脚本,如果你是通过跳板机去连接目标服务器,千万不要在执行命令的 SSH 中加 -t 。
错误写法(会导致卡在跳板机):

ssh -t "${user}@${server}" "$(declare -f remoteCMD; remoteCMD)"

正确写法(自动执行完退出):

ssh "${user}@${server}" "$(declare -f remoteCMD; remoteCMD)"

看命令执行完后,是否需要“手动输入东西”或者“进入另一个交互式环境”。

✅ 需要加 -t 的情况(交互式)
当你执行的命令会启动一个等待用户输入的程序,且你不希望 SSH 连接在程序启动后立即断开。
1. 启动交互式 Shell:
● 你只是想登录进去手动操作。
● ssh user@server
● ssh user@server "bash" (启动了一个新的 Shell,需要你输入命令)
2. 运行需要键盘输入的程序:
● ssh user@server "sudo some_command" (需要你输入密码)
● ssh user@server "vim /etc/config.txt" (需要你编辑文件)
● ssh user@server "python" (进入 Python 交互解释器)
3. 运行全屏程序:
● ssh user@server "top"
● ssh user@server "htop"
● ssh user@server "mysql -u root -p" (需要输入数据库密码)

如果不加 -t 会怎样?
● 命令可能会报错(例如 sudo: no tty present )。
● 或者程序一闪而过(比如 top 刚打开就退出了),因为程序发现没有终端可以显示画面。

❌ 不需要加 -t 的情况(非交互式/自动化)
当你执行的命令是“干完活就跑”的,不需要人盯着屏幕或者手动输入。

1. 执行单条命令:
● ssh user@server "ls /tmp"
● ssh user@server "df -h"
● ssh user@server "systemctl restart nginx"
2. 执行脚本/函数:
● 也就是你现在的场景,你的 remoteCMD 函数。
● ssh user@server "bash /path/to/script.sh"
3. 数据传输/查询:
● ssh user@server "cat /var/log/error.log"
● ssh user@server "ps aux | grep java"

如果误加了 -t 会怎样?
● 在单层 SSH 时:通常没太大副作用,只是多分配了一个不必要的终端资源。
● 在多层 SSH(跳板机)时:灾难性的。会导致连接卡在中间层,无法自动透传命令,必须手动 exit 才能退出。

*Tesla*的主页 *Tesla* | 小虾三级 | 园豆:1274
提问于:2025-12-26 07:59
< >
分享
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册