我正在编写一个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
我希望根据给定的IdentityFile
获取Hostname
之后的字符串,并将其放入变量中。主机名将由名为${HOSTNAME}
的shell变量提供。
我能够使用Bash extract user for a particular host from ssh config file上的答案来阅读配置文件,并根据单个特定IdentityFile
来查看单个特定Hostname
的grep,但我无法理解把变量传递给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变量,我错过了什么?有更好的方法吗?
答案 0 :(得分:2)
使用GNU grep和Perl兼容的正则表达式:
hostname="AAAA"
grep -Poz "Host $hostname(.*\n)*?.*IdentityFile \K.*" ~aaaa/.ssh/config
输出:
/home/aaaa/.ssh/aaaaFILE
答案 1 :(得分:2)
我很欣赏脚本尝试,但OpenSSH客户端已经知道如何解析配置:
ssh -G $hosname | grep identityfile | awk '{print $2}' | head -n 1
请注意,它还会列出默认身份,但是IdentitiesOnly=yes
它应该列出配置中的一个作为第一个。
答案 2 :(得分:1)
mmm由于某种原因,您发布的示例在主机字之前具有奇怪的不可打印字符。此正则表达式仅匹配第一行:/^Host/
,而它应匹配总共3行。
我通过删除这些字符并再次保存来修复它。
所以,回答你的问题,你不能在awk的正则表达式中使用变量。
但这也有效并且做同样的事情:
HOSTNAME="BBBB"
awk -v host=$HOSTNAME '/Host/ && $2==host {found=1} /IdentityFile/ && found {print $2; exit}' ${SSH_CONFIG}