You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

本地经ip-address1跳转SSH至ip-address2,多命令执行异常求助

问题分析与解决方案

这问题我太熟了——核心就是shell的引号解析顺序在搞鬼!

你的原始命令里,外层的双引号"pwd; ls;"会被本地shell先处理,当这条命令传递到ip-address1时,实际上变成了:

ssh -tt -i /root/.ssh/vm_private_key user@ip-address2 pwd; ls;

看到没?分号把命令拆成了两部分:ssh ... pwd和ls。所以pwd会在ip-address2上执行,等ssh连接关闭后,ls就跑到ip-address1上执行了,这就是你看到输出顺序混乱的原因。

下面给你三种靠谱的解决办法:

方法1:用单引号包裹内层SSH命令

把ip-address1上要执行的整个ssh命令用单引号包起来,这样本地shell不会解析里面的双引号和分号,完整传递给ip-address1的shell:

sshpass -p mypassword ssh -tt user@ip-address1 'ssh -tt -i /root/.ssh/vm_private_key user@ip-address2 "pwd; ls;"'

单引号会阻止本地shell对内容做任何解析,确保"pwd; ls;"作为一个整体传递给ip-address2的shell,两条命令都会在目标机器上执行。

方法2:用Here Document(适合多命令场景)

如果以后要执行更多命令,用Here Document会更清晰,可读性更强:

sshpass -p mypassword ssh -tt user@ip-address1 << 'EOF'
ssh -tt -i /root/.ssh/vm_private_key user@ip-address2 << 'INNER_EOF'
pwd
ls
INNER_EOF
EOF

这里的'EOF'和'INNER_EOF'加了单引号,防止本地shell解析里面的变量或特殊字符,确保所有命令都严格在ip-address2上执行。

方法3:用ProxyJump(最简洁,推荐)

如果你的OpenSSH版本≥7.3(大部分现代系统都满足),直接用-J参数做代理跳转,彻底避免嵌套SSH的引号问题:

sshpass -p mypassword ssh -tt -J user@ip-address1 -i /root/.ssh/vm_private_key user@ip-address2 "pwd; ls;"

-J参数会让本地SSH直接通过ip-address1作为跳板连接到ip-address2,所有命令直接传递给目标机器,逻辑更简单,也不容易出错。

试一下上面的方法,你会看到pwd和ls的输出都在Connection to ip-address2 closed.之前出现,完美解决问题!

内容的提问来源于stack exchange,提问作者Ciaran Whyte

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:52:19