Как получить правильные ключи и значения из JQ в массив в сценарии оболочки Bash - PullRequest
0 голосов
/ 28 октября 2019

У меня есть файл json, который отформатирован следующим образом:

{
  "ServerName1": {
    "localip": "192.168.1.1",
    "hostname": "server1"
  },
  "ServerName2": {
    "localip": "192.168.1.2",
    "hostname": "server2"
  },
  "ServerName3": {
    "localip": "192.168.1.3",
    "hostname": "server3"
  }
}

И я пытаюсь написать сценарий оболочки, который использует Dialog для создания меню для запуска команды подключения ssh. Я анализирую с jq, но не могу пройти первый уровень объекта. У нас много серверов, и это значительно облегчит подключение к ним. У меня есть оператор Dialog, который отлично работает со статическими данными, но мы пытаемся заполнить его файлом json с остальными данными. Поэтому я убиваю себя, пытаясь выяснить, как получить только localip и имя хоста либо в массив для зацикливания в команде Dialog, либо что-то, что будет эффективно делать то же самое, и все, что я пока делаю, это выплевывать

Servername1 = {"localip":"192.168.1.1","hostname":"server1"}

в каждой строке. Я новичок в скриптовом сценарии, но сейчас это портит здравомыслие.

Это команда jq, с которой я работал до сих пор:

jq -r "to_entries|map(\"\(.key)=\(.value|tostring)\")|.[]" config.json

Это команда Dialog, которая хорошо работает со статическими данными:

callssh(){
  clear
  ssh $1@$2
}

## Display Menu ##
dialog --clear --title "SSH Relayer"\
    --menu "Please choose which server \n\
    with which you would like to connect" 15 50 4 \ 
    "Server 1" "192.168.1.1"\
    "Server 2" "192.168.1.2"\
    "Server 3" "192.168.1.3"\
    Exit "Exit to shell" 2>"${INPUT}"

menuitem=$(<"${INPUT}")

case $menuitem in
    "Server 1") callssh $sshuser 192.168.1.1;;
    "Server 2") callssh $sshuser 192.168.1.2;;
    "Server 3") callssh $sshuser 192.168.1.3;;
    Exit) clear 
          echo "Bye!";;
esac

Спасибо за любую помощь или указание в правильном направлении.

1 Ответ

1 голос
/ 29 октября 2019

Чтобы создать массив bash, сопоставляющий имена хостов с ip-адресами на основе config.json:

declare -A ip_of

# Emit lines of the form:
# hostname localip (without quotation marks)
function hostname_ip {
 local json="$1"
 jq -r '.[] | "\(.hostname) \(.localip)"' "$json"
}

while read -r hostname ip ; do
    ip_of["$hostname"]="$ip"
done < <(hostname_ip config.json)

Вы можете пройти через этот массив bash следующим образом:

for hostname in "${!ip_of[@]}" ; do
  echo hostname=$hostname "=>" ${ip_of[$hostname]}
done

Например,предполагая, что «диалог» представляет имена хостов, вы можете заменить оператор case на:

callssh "$sshuser" "${ip_of[$menuitem]}"
...