Har*_*jan 2 shell bash ssh quoting ssh-config
我在 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
Run Code Online (Sandbox Code Playgroud)
为了简化这个过程,我想我会创建一个环境变量来保存 proxycommand 并简单地使用它。所以我做了
export PGWA='-o ProxyCommand="ssh gateway1 nc %h %p"'
export PGWB='-o ProxyCommand="ssh gateway2 nc --proxy %h %p --proxy-type socks4"'
Run Code Online (Sandbox Code Playgroud)
然后,根据我想连接的机器,我会做
ssh $PGWA machine_behind_1
ssh $PGWB machine_behind_2
Run Code Online (Sandbox Code Playgroud)
但我收到这个错误 -
/bin/bash: -c: line 0: unexpected EOF while looking for matching `"'
/bin/bash: -c: line 1: syntax error: unexpected end of file
Run Code Online (Sandbox Code Playgroud)
知道为什么吗?
我不能使用任何 ssh_config 技巧,因为我提前不知道主机名。我可能会在 gateway1 后面创建一个新的 VM,我将需要使用第一个代理命令。
我唯一能想到的就是创建一个新的别名、一个函数或一个 shell 脚本,它们基本上ssh -o foo $@可以代替并使用它。但是,我还需要记住为 scp 创建别名/shell 脚本或函数,我也经常使用它。我宁愿能够自动完成。
我有点希望我可以做一些类似的事情ssh gw1-host并在配置文件中进行一些操作以ssh -o foo host通过第一个网关将其转换为,但是在 ssh_config.xml 中不允许这种正则表达式操作。
没有单独的 ssh/scp 别名/脚本/函数,我可以通过什么方式实现我想要的?
编辑:当我将环境变量复制粘贴到堆栈交换中时,我在引用时犯了一个错误。
当您$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 …
Run Code Online (Sandbox Code Playgroud)
在 bash 和 ksh 等其他 shell 中,这需要更多的输入,因为它们的设计缺陷是不带引号的变量扩展会进行拆分,并且因为它们对数组的显式语法:
PGWA=(-o 'ProxyCommand=ssh gateway2 nc --proxy %h %p --proxy-type socks4')
ssh "${PGWA[@]}" …
Run Code Online (Sandbox Code Playgroud)
可以在任何类似 sh 的 shell 中工作并且不需要太多输入的方法是定义函数。
pgwa () {
typeset c="$1"; shift
"$c" -o 'ProxyCommand=ssh gateway2 nc --proxy %h %p --proxy-type socks4' "$@"
}
pgwa ssh …
Run Code Online (Sandbox Code Playgroud)
但我认为最好的解决方案是将所有这些定义放在.ssh/config它们所属的位置。这样你就不需要任何 shell 技巧,并且配置可以在其他程序(rsync、sshfs、GUI 文件传输程序等)中工作。如果在 gateway1 后面添加新 VM,请添加条目.ssh/config或使用ssh -o HostName=new-vm something-behind-gateway1 …
¹加上其他在这里无关紧要的事情。