2012-09-21 7 views
28

So habe ich ein bash Skript, das Details auf Servern ausgibt. Das Problem ist, dass ich brauche, dass der Ausgang JSON ist. Was ist der beste Weg, dies zu tun? Hier ist die Bash-Skript:Ausgabe von JSON aus Bash-Skript

# Get hostname 
hostname=`hostname -A` 2> /dev/null 

# Get distro 
distro=`python -c 'import platform ; print platform.linux_distribution()[0] + " " +  platform.linux_distribution()[1]'` 2> /dev/null 

# Get uptime 
if [ -f "/proc/uptime" ]; then 
uptime=`cat /proc/uptime` 
uptime=${uptime%%.*} 
seconds=$((uptime%60)) 
minutes=$((uptime/60%60)) 
hours=$((uptime/60/60%24)) 
days=$((uptime/60/60/24)) 
uptime="$days days, $hours hours, $minutes minutes, $seconds seconds" 
else 
uptime="" 
fi 

echo $hostname 
echo $distro 
echo $uptime 

So ist der Ausgang ich will, ist so etwas wie:

{"hostname":"server.domain.com", "distro":"CentOS 6.3", "uptime":"5 days, 22 hours, 1 minutes, 41 seconds"} 

Dank.

+6

Gibt es einen Grund, den Sie nicht alles von Python tun möchten? Ich meine, Sie verwenden es trotzdem, und Python kann den Hostnamen leicht ermitteln, die Betriebszeit lesen und den gewünschten JSON generieren. – willglynn

Antwort

55

Ersetzen Sie Ihre drei echo Befehle am Ende des Skriptes mit:

echo -e "{\"hostname\":\""$hostname"\", \"distro\":\""$distro"\", \"uptime\":\""$uptime"\"}" 

die -e ist für ermöglichen Interpretation von Backslash

oder mit diesem:

printf '{"hostname":"%s","distro":"%s","uptime":"%s"}\n' "$hostname" "$distro" "$uptime" 

Some von den neueren Distributionen, haben Sie eine Datei mit dem Namen: /etc/lsb-release oder ähnlichen Namen (cat /etc/*release). Daher könnten Sie möglicherweise abschaffen Ihr auf Python mit Abhängigkeit:

distro=$(awk -F= 'END { print $2 }' /etc/lsb-release) 

Nebenbei bemerkt, sollten Sie wahrscheinlich tun, weg mit Backticks. Sie sind ein bisschen altmodisch.

+11

'printf' wäre etwas sauberer:' printf '{"Hostname": "% s", "Distro": "% s", "Uptime": "% s"} \ n' "$ hostname" "$ Distro "" $ uptime "' –

+1

Warum habe ich nicht daran gedacht? Danke Glenn :-) – Steve

+0

Upvote für printf, da es auch auf BSDs zu funktionieren scheint. Zumindest in OSX hat 'echo' nicht die '-e'-Option von dem, was ich im Handbuch sehen kann. –

29

Ich finde es viel einfacher, die json erstellen cat mit:

cat <<EOF > /your/path/myjson.json 
{"id" : "$my_id"} 
EOF 
+0

Genau das, was ich gesucht habe. Vielen Dank – Veera

2

Ich bin kein bash-ninja überhaupt, aber ich schrieb eine Lösung, die perfekt funktioniert für mich. Also, ich entschied to share it mit der Gemeinschaft.

Zunächst einmal habe ich ein Bash-Skript namens json.sh

arr=(); 

while read x y; 
do 
    arr=("${arr[@]}" $x $y) 
done 

vars=(${arr[@]}) 
len=${#arr[@]} 

printf "{" 
for ((i=0; i<len; i+=2)) 
do 
    printf "\"${vars[i]}\": ${vars[i+1]}" 
    if [ $i -lt $((len-2)) ] ; then 
     printf ", " 
    fi 
done 
printf "}" 
echo 

Und jetzt kann ich es leicht ausführen:

$ echo key1 1 key2 2 key3 3 | ./json.sh 
{"key1":1, "key2":2, "key3":3} 
1

@Jimilian Skript für mich sehr hilfreich war. Habe ich es ein wenig Daten

arr=() 

while read x y; 
do 
    arr=("${arr[@]}" $x $y) 
done 

vars=(${arr[@]}) 
len=${#arr[@]} 

printf "{\n" 
printf "\t"data":[\n" 

for ((i=0; i<len; i+=2)) 
do 
    printf "\t{ "{#VAL1}":\"${vars[i]}\",\t"{#VAL2}":\"${vars[i+1]}\" }" 

    if [ $i -lt $((len-2)) ] ; then 
     printf ",\n" 
    fi 
done 
printf "\n" 
printf "\t]\n" 
printf "}\n" 
echo 

Ausgabe an zabbix auto discovery zu senden:

$ echo "A 1 B 2 C 3 D 4 E 5" | ./testjson.sh 
{ 
    data:[ 
    { {#VAL1}:"A", {#VAL2}:"1" }, 
    { {#VAL1}:"B", {#VAL2}:"2" }, 
    { {#VAL1}:"C", {#VAL2}:"3" }, 
    { {#VAL1}:"D", {#VAL2}:"4" }, 
    { {#VAL1}:"E", {#VAL2}:"5" } 
    ] 
} 
0

ich ein kleines Programm in Go schrieb, json_encode. Es funktioniert ziemlich gut für solche Fälle:

$ ./getDistro.sh | json_encode 
["my.dev","Ubuntu 17.10","4 days, 2 hours, 21 minutes, 17 seconds"]