web-dev-qa-db-fra.com

Sortie JSON à partir du script Bash

J'ai donc un script bash qui génère des détails sur les serveurs. Le problème est que j'ai besoin que la sortie soit JSON. Quelle est la meilleure manière de s'occuper de ça? Voici le 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

Donc, la sortie que je veux est quelque chose comme:

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

Merci.

40
Justin

Remplacez vos trois commandes echo à la fin de votre script par:

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

le -e est pour permettre l'interprétation des échappements antislash

ou avec ceci:

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

Certaines des distributions les plus récentes ont un fichier appelé: /etc/lsb-release ou nom similaire (cat /etc/*release). Par conséquent, vous pourriez éventuellement supprimer la dépendance de votre Python:

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

Soit dit en passant, vous devriez probablement supprimer l'utilisation de backticks. Ils sont un peu démodés.

74
Steve

Je trouve qu'il est beaucoup plus facile de créer le json en utilisant cat:

cat <<EOF > /your/path/myjson.json
{"id" : "$my_id"}
EOF
45
Leandro Mora

Je ne suis pas du tout un bash-ninja, mais j'ai écrit une solution qui fonctionne parfaitement pour moi. J'ai donc décidé de le partager avec la communauté.

Tout d'abord, j'ai créé un script bash appelé 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

Et maintenant, je peux facilement l'exécuter:

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

Le script @Jimilian m'a été très utile. Je l'ai un peu changé pour envoyer des données à découverte automatique zabbix

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

Sortie:

    $ 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"  }
    ]
}
1
Daro

J'ai écrit un petit programme dans Go, json_encode . Cela fonctionne assez bien dans de tels cas:

$ ./getDistro.sh | json_encode
["my.dev","Ubuntu 17.10","4 days, 2 hours, 21 minutes, 17 seconds"]
1
Fedir RYKHTIK
data=$(echo  " BUILD_NUMBER : ${BUILD_NUMBER} , BUILD_ID : ${BUILD_ID} , JOB_NAME : ${JOB_NAME} " | sed 's/ /"/g')

output => data="BUILD_NUMBER":"29","BUILD_ID":"29","JOB_NAME":"OSM_LOG_ANA"
0
Navaganesh R