【问题标题】:SSHing into several hosts sequentially from my local machine with one command使用一个命令从我的本地计算机按顺序通过 SSH 连接到多个主机
【发布时间】:2019-05-14 23:46:06
【问题描述】:

我目前正在尝试编写一个别名,该别名涉及从我的本地机器通过 SSH 连接到一台主机,然后我再通过 SSH 连接到最后一台机器。我的 bash 技能还没有达到标准,我似乎无法弄清楚发生了什么。

这就是我所拥有的

ssh -A my_user@host_1 -t "get_ip | sed -n 2p | xargs -I {} ssh -T my_user@{}"

最终我想做的是从我的本地机器上运行一个命令:

  1. 将我通过 SSH 连接到初始远程计算机。在这里我想运行 get_ip 并解析它的输出,这给了我一个 IP
  2. 第一步中的 IP 是我想要通过 SSH 连接到的最后一个服务器,并让活动会话运行(不想只是退出)。这就是我在命令的最后一部分尝试做的事情。

换句话说:

在本地机器上运行命令 -> 在第一台远程服务器上运行命令并使用该命令的输出来获取下一台机器的 ip -> 使用我检索到的 IP SSH 到最后一台机器 -> 有一个打开的会话最后一台机器 SSH 进入

现在我当前的命令正在返回:

Connection to host_1 closed

【问题讨论】:

  • “用一个命令”有什么特别的原因吗?做到这一点的最佳方法——允许您将任意端口转发到最后一跳机器,而无需先将这些端口转发到第一跳机器——需要使用 SSH多路复用以在多个后续命令中重用相同的连接。
  • 想通过写一个别名来改进我的工作流程。
  • Shell 函数(可以根据需要包含任意数量的命令)几乎总是比别名更可取。事实上,“别名”的 freenode #bash 事实是“如果你不得不问,请改用函数”。
  • 如果您不接受 bash 答案,请删除 bash 标签。 zsh 与 bash 不兼容,它不是 bash 的超集,不适合用“bash”标签标记 zsh 问题。
  • Gotcha 为造成的混乱道歉。将删除 bash。

标签: ssh terminal zsh


【解决方案1】:

设置管道会替换标准输入(因此输入来自现在为空的管道,而不是来自您原来的终端)。使用命令替换代替xargs,并使用-tt 强制在每个阶段分配一个TTY:

ssh -ttA my_user@host_1 'ssh -tt "my_user@$(get_ip | sed -n 2p)"'

更好:

sshWithCache() {
  ssh \
    -o "ControlPath $HOME/.ssh/control:%h:%p:%r" \
    -o "ControlMaster auto" \
    -o "ControlPersist 5m" \
    "$@"
}

sshIndirectly() {
  local ip
  ip=$(sshWithCache my_user@host_1 'get_ip | sed -n 2p')
  sshWithCache -o "ProxyJump my_user@host_1" "my_user@$ip" "$@"
}

...之后,您可以运行 sshIndirectly someCommand 以在 host_2 上调用 someCommand。由于ControlPath/ControlMaster 配置,只创建了一个到host_1 的实际SSH 连接,并且只执行了一次身份验证。

【讨论】:

  • 获取zsh: no matches found: ssh -tt "my_user@$(get_ip | sed -n 2p)"
  • 代码针对 bash 进行了测试——这是你的问题被标记的 shell——而不是 zsh。 zsh 故意不符合 POSIX sh 标准,我不支持/认可/宽恕/协助他人使用它。
  • 出于好奇,较长的(双功能)形式是否适用于 zsh,或者您是否有同样的问题?如果失败,您是否会收到更清楚地缩小问题范围的错误消息?
  • 当我尝试两种功能方法时它挂起。
  • set -x; sshIndirectly 写的最后一行是什么?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-22
  • 2015-11-27
  • 2017-06-08
  • 1970-01-01
  • 1970-01-01
  • 2018-12-11
相关资源
最近更新 更多