通过 shell 脚本基于变量主机名从 ssh 配置中获取 IdentityFile
Posted
技术标签:
【中文标题】通过 shell 脚本基于变量主机名从 ssh 配置中获取 IdentityFile【英文标题】:Grab an IdentityFile from an ssh config based on a variable hostname via shell script 【发布时间】:2018-01-22 18:39:47 【问题描述】:我正在编写一个 shell 脚本,我需要从 ssh 配置文件中获取 IdentityFile
。 ssh 配置文件如下所示:
Host AAAA
User aaaa
IdentityFile /home/aaaa/.ssh/aaaaFILE
IdentitiesOnly yes
PubkeyAuthentication=yes
PreferredAuthentications=publickey
Host BBBB
User bbbb
IdentityFile /home/aaaa/.ssh/bbbbFILE
IdentitiesOnly yes
PubkeyAuthentication=yes
PreferredAuthentications=publickey
Host CCCC
User cccc
IdentityFile /home/aaaa/.ssh/ccccFILE
IdentitiesOnly yes
PubkeyAuthentication=yes
PreferredAuthentications=publickey
我想根据给定的Hostname
获取IdentityFile
之后的字符串并将其放入变量中。主机名将由名为 $HOSTNAME
的 shell 变量提供。
我能够使用Bash extract user for a particular host from ssh config file 的答案来读取配置文件并根据单个特定Hostname
grep 获取单个特定IdentityFile
,但我无法掌握将变量传递到啊。
到目前为止我已经尝试过
SSH_CONFIG="/home/aaaa/.ssh/config"
# Note AAAA is the hostname for this case
KEY=$(awk '/^Host AAAA$/x=1x&&/IdentityFile/print $2;exit' $SSH_CONFIG)
echo "$KEY"
OUTPUT: "/home/aaaa/.ssh/aaaaFILE"
这很有效,因为我给出了要解析的确切主机名。 但是使用
SSH_CONFIG="/home/aaaa/.ssh/config"
HOSTNAME=AAAA
KEY=$(awk -vcon="$HOSTNAME" '/^Host con$/x=1x&&/IdentityFile/print $2;exit' $SSH_CONFIG)
echo "$KEY"
OUTPUT: ""
不起作用。我知道一个事实 $HOSTNAME
正在设置,因为我正在设置自己(并回应它)。我想传递一个变量,因为我不希望主机名硬编码,并且在调用脚本之前不知道该值是什么。
我也一直在使用旧版本的 ssh (OpenSSH_6.6.1),它没有方便的 ssh -G HOSTNAME
选项。
关于 awk 变量,我缺少什么?有没有更好的方法来做到这一点?
【问题讨论】:
【参考方案1】:我很欣赏脚本尝试,但 OpenSSH 客户端已经知道如何解析配置:
ssh -G $hosname | grep identityfile | awk 'print $2' | head -n 1
请注意,它还会列出默认身份,但对于 IdentitiesOnly=yes
,它应该将配置中的身份列为第一个。
【讨论】:
正如我上面提到的,我也被困在使用旧版本的 ssh (OpenSSH_6.6.1),它没有方便的 ssh -G HOSTNAME 选项。除非你想为我推出一个 Debian 软件包,否则我会被困在没有ssh -G
的脚本上。
@Wimateeka 抱歉,我错过了那部分。也许是时候更新了?
很遗憾,这不是我的决定,但相信我,我很乐意更新。由于这个原因,我已经对没有 sshpass 的详细选项感到厌烦。【参考方案2】:
使用 GNU grep 和 Perl 兼容的正则表达式:
hostname="AAAA"
grep -Poz "Host $hostname(.*\n)*?.*IdentityFile \K.*" ~aaaa/.ssh/config
输出:
/home/aaaa/.ssh/aaaaFILE【讨论】:
感谢@Cyrus 的这个建议。这对我有用。我选择你的答案是因为grep
允许更简洁。【参考方案3】:
嗯,出于某种原因,您发布的示例在 Host 字之前有奇怪的不可打印字符。这个正则表达式只匹配第一行:/^Host/
,而它应该匹配总共 3 行。
我通过删除这些字符并再次保存来解决这个问题。
所以,回答你的问题,你不能在 awk 的正则表达式中使用变量。
但这也有效并且做同样的事情:
HOSTNAME="BBBB"
awk -v host=$HOSTNAME '/Host/ && $2==host found=1 /IdentityFile/ && found print $2; exit' $SSH_CONFIG
【讨论】:
感谢@valrog 的这个建议。这对我有用。以上是关于通过 shell 脚本基于变量主机名从 ssh 配置中获取 IdentityFile的主要内容,如果未能解决你的问题,请参考以下文章
利用shell脚本执行ssh远程另一台主机执行命令并返回命令的结果集
通过ssh主机互信打通内外网,使用shell脚本自动部署测试环境
shell脚本怎么实现A主机SSH到B主机,在从B主机SSH到C主机,然后在C主机执行ps -ef命令返回C主机的进程数