Получите 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 extract для конкретного хоста из файла конфигурации 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? Есть лучший способ сделать это?
3 ответа
С GNU grep и регулярными выражениями, совместимыми с Perl:
hostname="AAAA"
grep -Poz "Host $hostname(.*\n)*?.*IdentityFile \K.*" ~aaaa/.ssh/config
Выход:
/home/aaaa/.ssh/aaaaFILE
Я ценю попытки написания сценариев, но клиент OpenSSH уже знает, как анализировать конфигурацию:
ssh -G $hosname | grep identityfile | awk '{print $2}' | head -n 1
обратите внимание, что в нем также будут перечислены идентификаторы по умолчанию, но с IdentitiesOnly=yes
он должен перечислить тот из конфигурации как первый.
Ммм, почему-то, пример, который вы разместили, содержит странные непечатаемые символы перед словом " хост" Это регулярное выражение соответствует только первой строке: /^Host/
, в то время как он должен соответствовать 3 всего строк.
Я исправил это, удалив эти символы и сохранив их снова.
Итак, отвечая на ваш вопрос, вы не можете использовать переменные внутри регулярного выражения в awk.
Но это также работает и делает то же самое:
HOSTNAME="BBBB"
awk -v host=$HOSTNAME '/Host/ && $2==host {found=1} /IdentityFile/ && found {print $2; exit}' ${SSH_CONFIG}