Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/facebook/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
通过shell脚本根据变量主机名从ssh配置中获取标识文件_Shell_Parsing_Awk_Ssh_Ssh Config - Fatal编程技术网

通过shell脚本根据变量主机名从ssh配置中获取标识文件

通过shell脚本根据变量主机名从ssh配置中获取标识文件,shell,parsing,awk,ssh,ssh-config,Shell,Parsing,Awk,Ssh,Ssh Config,我正在编写一个shell脚本,需要从ssh配置文件中获取一个IdentityFile。ssh配置文件如下所示: ​Host AAAA User aaaa IdentityFile /home/aaaa/.ssh/aaaaFILE IdentitiesOnly yes PubkeyAuthentication=yes PreferredAuthentications=publickey ​Host BBBB User bbbb Identit

我正在编写一个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}
的shell变量提供

我能够使用上的答案读取配置文件,并根据单个特定的主机名读取单个特定的
IdentityFile
,但我无法掌握将变量传递到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主机名
选项。


谈到awk变量,我遗漏了什么?有更好的方法吗?

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

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

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

我通过删除这些字符并再次保存来修复这个问题

所以,回答你的问题,你不能在awk的正则表达式中使用变量

但这同样有效:

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

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

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

请注意,它还将列出默认标识,但如果使用
identiesonly=yes
,则应将配置中的标识列为第一个标识。

如上所述,我还一直在使用ssh的旧版本(OpenSSH_6.6.1),该版本没有方便的ssh-G主机名选项。除非你想为我推出一个Debian软件包,否则我无法编写sans
ssh-G
@Wimateeka的脚本。对不起,我错过了这一部分。也许是时候更新了?不幸的是,这不是我的决定,但相信我,我很想更新。我已经因为没有一个详细的sshpass选项而被激怒了。谢谢这个建议@valrog。这对我有用。谢谢你的建议@Cyrus。这对我有用。我选择你的答案是因为
grep
更简洁。