我在 2 个网关后面有一堆 Linux 机器。要连接到我做的设置
ssh -o ProxyCommand="ssh gateway1 nc %h %p" machines_behind_1
ssh -o ProxyCommand="ssh gateway2 nc --proxy %h %p --proxy-type socks4" machines_behind_2
为了简化这个过程,我想我应该创建一个环境变量来保存代理命令并简单地使用它。所以我做了
export PGWA='-o ProxyCommand="ssh gateway1 nc %h %p"'
export PGWB='-o ProxyCommand="ssh gateway2 nc --proxy %h %p --proxy-type socks4"'
然后,根据我想要连接的机器,我会这样做
ssh $PGWA machine_behind_1
ssh $PGWB machine_behind_2
但我收到这个错误 -
/bin/bash: -c: line 0: unexpected EOF while looking for matching `"'
/bin/bash: -c: line 1: syntax error: unexpected end of file
知道为什么吗?
我无法使用任何 ssh_config 技巧,因为我事先不知道主机名。我可能会在 gateway1 后面创建一个新的虚拟机,并且我需要使用第一个代理命令。
我唯一能想到的就是创建一个新的别名、一个函数或一个 shell 脚本,基本上可以ssh -o foo $@
使用它来代替。但是,我还需要记住为 scp 创建一个别名/shell 脚本或函数,我也经常使用它。我宁愿能够自动完成它。
我有点希望我可以做一些类似的事情ssh gw1-host
,并在配置文件中进行一些操作,以ssh -o foo host
通过第一个网关将其转换,但是 ssh_config 中不允许进行这种正则表达式操作。
有什么方法可以在没有单独的 ssh / scp 别名/脚本/函数的情况下实现我想要的目标吗?
编辑:当我将环境变量复制粘贴到此处的堆栈交换时,我在引用中犯了一个错误。
答案1
当您不带引号编写时,这会分割at 空白$PGWA
的值。PGWA
引号字符在那里没有特殊含义,因此最终会得到单词-o
, ProxyCommand="ssh
, gateway1
, nc
,%h
和%p"
。
看为什么我的 shell 脚本会因为空格或其他特殊字符而卡住?以获得更多解释。
双引号之外的变量扩展几乎总是错误的。除非您知道为什么需要去掉双引号,否则这总是一个错误。
您需要做的是将两个参数传递给 SSH 命令:-o
和ProxyCommand=ssh gateway2 nc --proxy %h %p --proxy-type socks4
。
在 zsh 中,您可以设置PGWA
为一个数组:
PGWA=(-o 'ProxyCommand=ssh gateway2 nc --proxy %h %p --proxy-type socks4')
ssh $PGWA …
在 bash 和 ksh 等其他 shell 中,这需要更多的输入,因为它们的设计缺陷是未加引号的变量扩展会被分割,并且因为它们的显式数组语法:
PGWA=(-o 'ProxyCommand=ssh gateway2 nc --proxy %h %p --proxy-type socks4')
ssh "${PGWA[@]}" …
一种可以在任何类似 sh 的 shell 中工作并且不需要太多输入的方法是定义函数。
pgwa () {
typeset c="$1"; shift
"$c" -o 'ProxyCommand=ssh gateway2 nc --proxy %h %p --proxy-type socks4' "$@"
}
pgwa ssh …
但我认为最好的解决方案是将所有这些定义放在它们.ssh/config
所属的位置。这样您就不需要任何 shell 技巧,并且配置可以在其他程序(rsync、sshfs、GUI 文件传输程序等)中工作。如果您在 gateway1 后面添加新虚拟机,请添加一个条目.ssh/config
或使用ssh -o HostName=new-vm something-behind-gateway1 …
加上其他在这里不重要的事情。