I'm new to Linux and Bash scripting. I am trying to output several bash scripts in Ubuntu Linux into JSON format, however, I cannot seem to get it to work properly.
My goal is to get this:
date -u +%Y-%m-%d:%H:%M:%S //date and time
lsb_release -a //os distro version
ifconfig -a //ip info
Into this format in 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}],
2 Answers 2
Bash itself has no JSON support. Thus, to guarantee conformance, you need to use an external utility with JSON parsing and generation support built in. jq is one of these, and the below uses its built-in regex support:
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 ')
See this code in action on JQPlay.
If you can't install tools not built into your Linux distro, consider 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)"
2 Comments
Something like that should be quite easy to do with jo:
jo datetime=$(date -u +%Y-%m-%d:%H:%M:%S) osversion=$(lsb_release -a) ip_info=$(jo -a $(ip -o addr list))
2 Comments
jo
parse ip -o addr list
into fields here? I don't see how it could get the desired output format.jo
.
ifconfig
; it's an ancient tool nobody has maintained in over a decade. If you want to list IPs on Linux in a way that works with new and modern parts of the network stack, useip -o addr list
.gateway
isn't present in the output ofifconfig -a
. Since the routing table isn't interface-specific, one wouldn't really expect them to be stored/managed together...