2012-09-21 40 views
28

Tengo un script bash que muestra los detalles en los servidores. El problema es que necesito que la salida sea JSON. ¿Cuál es la mejor manera de hacerlo? Aquí está la escritura del golpe:Salida JSON del script Bash

# 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 

lo que la salida que quiero es algo así como:

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

Gracias.

+6

¿Hay alguna razón por la que no desee hacer todo esto desde Python? Es decir, lo estás usando de todos modos, y Python puede determinar fácilmente el nombre de host, leer el tiempo de actividad y generar el JSON que deseas. – willglynn

Respuesta

55

reemplazar sus tres echo comandos al final de la secuencia de comandos con:

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

la -e es para permitir la interpretación de la barra invertida se escapa

o con esto:

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

Algunos de las distribuciones más recientes, tenga un archivo llamado: /etc/lsb-release o nombre similar (cat /etc/*release). Por lo tanto, usted podría posiblemente acabar con la dependencia de su Python:

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

un lado, probablemente debería acabar con el uso de acentos abiertos. Están un poco anticuados.

+11

'printf' sería un poco más limpio:' printf '{"hostname": "% s", "distro": "% s", "uptime": "% s"} \ n' "$ hostname" "$ distro "" $ uptime "' –

+1

¿Por qué no pensé en eso? Gracias Glenn :-) – Steve

+0

Votación hacia arriba para printf ya que parece funcionar también en BSD. Al menos en OSX, 'echo' no tiene la opción '-e' de lo que puedo ver en el manual. –

29

Me resulta mucho más fácil de crear el JSON usando cat:

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

Exactamente lo que estaba buscando. Gracias – Veera

2

No soy una fiesta-ninja en absoluto, pero escribí una solución, que funciona perfectamente para mí. Entonces, decidí to share it con la comunidad.

En primer lugar, he creado un script bash llamada 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 

Y ahora puede ejecutar fácilmente:

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

guión @Jimilian era muy útil para mí. He cambiado un poco para enviar datos a zabbix auto discovery

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 

Salida:

$ 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

me escribió un pequeño programa en Ir, json_encode. Funciona bastante bien en tales casos:

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