通过 shell 脚本从基于变量主机名的 ssh 配置中获取身份文件



我正在编写一个 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 提取用户从 ssh 配置文件中特定主机的答案来读取配置文件和基于单个特定IdentityFile的 grepHostname,但我无法掌握将变量传递到 awk 中的窍门。

到目前为止我已经尝试过

SSH_CONFIG="/home/aaaa/.ssh/config"
# Note AAAA is the hostname for this case
KEY=$(awk '/^Host AAAA$/{x=1}x&&/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=1}x&&/IdentityFile/{print $2;exit}' ${SSH_CONFIG})
echo "${KEY}" 
OUTPUT: ""

不起作用。我知道${HOSTNAME}被设置的事实,因为我正在设置自己(并回应它(。我想传递一个变量,因为我不希望主机名硬编码,并且在调用脚本之前不知道值是多少。

我也坚持使用旧版本的ssh(OpenSSH_6.6.1(,它没有方便的ssh -G HOSTNAME选项。

当涉及到awk变量时,我错过了什么?有没有更好的方法可以做到这一点?

我很欣赏脚本编写尝试,但OpenSSH客户端已经知道如何解析配置:

ssh -G $hosname | grep identityfile | awk '{print $2}' | head -n 1

请注意,它还将列出默认标识,但IdentitiesOnly=yes它应将配置中的标识列为第一个标识。

与 GNU grep 和 Perl 兼容的正则表达式:

hostname="AAAA"
grep -Poz "Host $hostname(.*n)*?.*IdentityFile K.*" ~aaaa/.ssh/config

输出:

/home/aaaa/
.ssh/aaaaFILE

嗯 出于某种原因,您发布的示例在Hostword之前有奇怪的不可打印字符。此正则表达式仅匹配第一行:/^Host/,而它应匹配总共 3 行。

我通过删除这些字符并再次保存来修复它。

因此,回答您的问题时,您不能在awk的正则表达式中使用变量。

但这也可以工作并做同样的事情:

HOSTNAME="BBBB"
awk -v host=$HOSTNAME '/Host/ && $2==host {found=1} /IdentityFile/ && found {print $2; exit}' ${SSH_CONFIG}

最新更新