2016-03-24 3 views
0

Я новичок в сценариях Linux и Bash. Я пытаюсь вывести несколько сценариев bash в Ubuntu Linux в формат JSON, однако я не могу заставить его работать правильно.вывод bash в формат json

Моя цель состоит в том, чтобы получить это:

date -u +%Y-%m-%d:%H:%M:%S //date and time 

lsb_release -a //os distro version 

ifconfig -a //ip info 

В этом формате в формате JSON:

"datetime":datetime_string, 

    "osversion":string, 

    "ip_info: [{"interface":string,"ip_addr":string,"mask":string,"gateway":string}, 
      {"interface":string,"ip_addr":string,"mask":string,"gateway":string}], 
+1

JQ - https://stedolan.github.io/jq/ - это ваш друг , –

+2

Кроме того, не используйте 'ifconfig'; это древний инструмент, который никто не поддерживал более десяти лет. Если вы хотите перечислить IP-адреса в Linux таким образом, чтобы работать с новыми и современными частями сетевого стека, используйте 'ip -o addr list'. –

+0

... btw, 'gateway' нет в выводе' ifconfig -a'. Поскольку таблица маршрутизации не специфична для интерфейса, на самом деле не ожидалось, что они будут храниться/управляться вместе ... –

ответ

0

Нечто подобное должно быть довольно легко сделать с помощью jo:

jo datetime=$(date -u +%Y-%m-%d:%H:%M:%S) osversion=$(lsb_release -a) ip_info=$(jo -a $(ip -o addr list)) 
+0

Как 'jo' parse' ip -o addr list' в полях здесь? Я не вижу, как он может получить желаемый формат вывода. –

+0

Кроме того, вам нужно больше кавычек, чтобы оболочка не разделяла строки с ключом/значением до того, как они будут переданы в 'jo'. –

0

Сам Баш не поддерживает JSON. Таким образом, чтобы гарантировать соответствие, вам нужно использовать внешнюю утилиту с JSON разборе и поддержки поколения, построенный в jq является одним из них, и ниже использует встроенный в регулярное выражение поддержки:.

jq --raw-input \ 
    --arg date "$(date)" \ 
    --arg osver "$(lsb_release -a)" \ 
    '{"date": $date, 
    "osver": $osver, 
    "ip_info": [inputs | 
       capture("^[0-9]+: (?<ifname>[^[:space:]]+)[[:space:]]+inet (?<addr>[^[:space:]/]+)(/(?<masklen>[[:digit:]]+))?") 
       ] 
    }' \ 
    < <(ip -o addr list | grep 'inet ') 

Смотрите этот код действие on JQPlay.


Если вы не можете установить средства не встроенные в Linux дистрибутив, рассмотрит Python:

#!/bin/bash 
#  ^^^^ - important, not /bin/sh; this uses some bash-only syntax 

py_code=$(cat <<'EOF' 
import json, re, sys 

content={'ip_info': []} 
for k, v in [ arg.split('=', 1) for arg in sys.argv[2:] if '=' in arg ]: 
    content[k]=v 

ip_re = re.compile(r'^[0-9]+:\s+(?P<ifname>\S+)\s+inet (?P<addr>[^/\s]+)(?:/(?P<masklen>\d+))?') 
for line in open(sys.argv[1]).readlines(): 
    m = ip_re.match(line) 
    if not m: raise "NOOOO" 
    content['ip_info'].append({ 
    'ifname': m.groups('ifname'), 
    'addr': m.groups('addr'), 
    'masklen': m.groups('masklen'), 
    }) 

print json.dumps(content) 
EOF 
) 

python -c "$py_code" \ 
    <(ip -o addr list | grep 'inet ') \ 
    "date=$(date)" "osver=$(lsb_release -a)" 
+0

Charles, как я могу написать это в Python 2.6.5 без jq? – Fadiddy

+0

@Fadiddy, см. Расширенный/исправленный ответ. –

Смежные вопросы