Возьмите IdentityFile из конфигурации ssh на основе переменного имени хоста через сценарий оболочки

Я пишу сценарий оболочки, в котором мне нужно получить IdentityFile из файла конфигурации ssh. Файл конфигурации 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}.

Я смог использовать ответ в извлечение Bash пользователь для определенного хоста из файла конфигурации ssh, чтобы прочитать файл конфигурации и grep для одного конкретного IdentityFile на основе одного конкретного Hostname, но я не могу понять, как передать переменную в 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? Есть лучший способ сделать это?


person Wimateeka    schedule 14.08.2017    source источник


Ответы (3)


С GNU grep и Perl-совместимыми регулярными выражениями:

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

Выход:

/home/aaaa/.ssh/aaaaFILE
person Cyrus    schedule 14.08.2017
comment
Спасибо за это предложение @Cyrus. Это сработало для меня. Я выбираю ваш ответ, потому что grep позволяет быть более кратким. - person Wimateeka; 15.08.2017

Я ценю попытки написания сценариев, но клиент OpenSSH уже знает, как анализировать конфигурацию:

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

обратите внимание, что он также будет перечислять идентификаторы по умолчанию, но с IdentitiesOnly=yes он должен указывать идентификатор из конфигурации как первый.

person Jakuje    schedule 15.08.2017
comment
Как я упоминал выше, я также застрял в использовании более старой версии ssh (OpenSSH_6.6.1), в которой нет удобной опции ssh -G HOSTNAME. Если вы не хотите выкатить для меня пакет Debian, я застрял в сценариях без ssh -G. - person Wimateeka; 15.08.2017
comment
@Wimateeka извините, я пропустил эту часть. Может пора обновить? - person Jakuje; 15.08.2017
comment
К сожалению, это не мое решение, но поверьте мне, я бы хотел обновить. Из-за этого я уже столкнулся с отсутствием подробной опции для sshpass. - person Wimateeka; 15.08.2017

ммм, по какой-то причине в опубликованном вами примере есть странные непечатаемые символы перед словом Host. Это регулярное выражение соответствует только первой строке: /^Host/, тогда как всего должно соответствовать 3 строкам.

Я исправил это, удалив эти символы и сохранив их снова.

Итак, отвечая на ваш вопрос, вы не можете использовать переменные внутри регулярного выражения в awk.

Но это также работает и делает то же самое:

HOSTNAME="BBBB"
awk -v host=$HOSTNAME '/Host/ && $2==host {found=1} /IdentityFile/ && found {print $2; exit}' ${SSH_CONFIG}
person valrog    schedule 14.08.2017
comment
Спасибо за это предложение @valrog. Это сработало для меня. - person Wimateeka; 15.08.2017